Recently, I needed to write a fairly complex class that had to be as lock-free as possible. While the code wouldn’t have ended up being too simple if I had written it using a regular, high-level lock (such as a read/write lock), it was quite complex with lock-free semantics, as I had to design a very specific contract which was hard to enforce.

Two separate, yet related, reasons are usually given when writing lock-free code. The first is that it provides added performance. The direct control you have over the code allows for domain-specific optimizations, and a lot of overhead of usual locks just isn’t there (most lock-free code is implemented with a locked compare-exchange instruction, which is, at the end of the day, how most locks are implemented). The second, more fundamental, reason is that lock-free code guarantees forward progress. From a conceptual point of view, it provides a simpler framework to reason about the concurrent semantics of what your code is doing.

As with all things in life, there are drawbacks. Locked compare-exchange instructions are expensive, and more times than not, you’ll end up having more instructions than if you had just used a regular lock. Perhaps more importantly, as hard as getting concurrent code with locks is correct, I honestly believe that getting concurrent lock-free code correct is at least an order of magnitude harder.

The question then is whether lock-free code is worth it. Well, it comes to whether a simple equation holds:

Cost(\textrm{Lock-Free Mental Hardship}) < Cost(\textrm{Lock Performance})

The answer, then, depends on the costs you assign. Personally, I don't think it's worth it, for a simple reason - I'm not smart enough. I don't fancy myself to be a genius programmer - every day at work I see countless people who are better at it than I am. However, I do believe I'm a decent programmer, but it really is too hard for me to get right, the point where any benefits I might have gotten have been nullified by a menacing trifecta of hard to maintain code, buggy code and long development time. Should've used locks in the first place.

This isn't to say that there aren't people out there who can do this right - there always have been, and there always are going to be. Yet they are few and far between, and as much as we'd like to think otherwise, most of us aren't them.

This of course applies beyond this specific issue. Many times using locks is too hard, and the solution is either to not have concurrent code (probably a bad idea), or find a different concurrent paradigm (e.g. no shared state concurrency, a la Erlang or CSP). The lesson to take to heart is that our code is much like our bodies. When we work out, we push ourselves, but only so much, because there are some things we just can’t do. If we push too much, we’ll get hurt. We should push ourselves to write better code and smarter code, but you don’t write an operating system in a day. If we push too hard with our code, it will find a myriad of ways to “break”. A day at a time, then.

That’s quite a stare.

(via Gruber, via The Singapore Grand Prix – The Big Picture – Boston.com)


How long would you have to wait? See you there in 11-16 years!

(via Panda, via Reason Magazine)


Standing in line...

I came across an interesting discussion on programming.reddit (the original link and the resulting discussion) about whether or not to use status code as return values to indicate success/failure, as opposed to using exceptions to indicate, well, exceptional cases.

I won’t repeat the pros and cons of either approach, as smarter people than me have done so. One reason for using status codes that I didn’t see mentioned is the ability to easily identify non-failing functions. Imagine you see the following interface:

Status DoThing1();
Status DoThing2();
Void   DoThing3();

By observation, you immediately know that the third function simply cannot fail, and no error-checking need be done. The counter argument is of course that if the function declares an exception then you have the same information, but as someone else said, where checked exceptions lie, so do dragons.

As to the title of this post, it was something new that I learnt today about something called the Samurai Principle:

Return Victoriously, or not at all.

That made my day.