QCon day two
Simple is not easy
Day number two started with a keynote by Rich Hickey (@richhickey) the author of Closure programming language. Honestly, I was technology marketing stuff like if Uncle Bob is speaking about Closure. Surprisingly to me, it was not the case. Rich didn’t even mention Closure. Instead, he was taking about what does it mean to be easy versus what does it mean to be simple.
Easy is something that is nearby (based on ancient origins of the word). It means that you don’t have to spend time to do what’s considered easy. For example writing stateful code is easy. Simple on the other hand is something that contains just one element. That property makes simple things understandable. You can reason about them. Each time you introduce another element into the concept, you make it more complex and thus harder to understand.
What surprised me was, Rich had courage to (just like Dan North and Greg Young did yesterday) say that automated tests alone are not enough to make your software easy to change. What makes it easy to change is ability to reason about the code.
Last but not least, Rich went through the list of things that are complex in software development (like classes, ordering of concepts, ORMs etc.) and, for each one, showed what simple concept can be used instead. During this part of presentation he actually started using Closure as an example (which was nice).
Finance: infrastructure and modelling
For the second and third slot I’ve chosen the financial track. I turned out to be great decision. Both sessions (by Todd Montgomery and Andrew Stewart) were very good. Todd (@toddlmontgomery) was talking about innovative ways of implementing reliable many-to-many communication for financial market solutions. The key to achieve really high throughput and low latency is getting rid of the message broker from the message transport path which means moving to peer-to-peer messaging. That’s great, but what about the reliability? Who would now be responsible for persisting messages and retransmitting in case of failure? Todd introduced a concept of redundant message stores. The publisher would first store the message and then send it to the receivers. If receiver fails or simply can’t cope with the rate messages are being sent, he can switch to ‘pull’ mode to fetch messages from one of the stores. Also, in such topology it is receiver who’s responsible for coordinating its own the failure recovery. This makes messages store a very simple thing to implement (compared to a broker).
Andrew Stuart was talking about the other side of the same coin – the modeling. Every system inevitably consists of a model and an infrastructure that allows the model to be executed. Fundamentally, every software system is a simulation of reality of some kind. The presentation was focused around the process people tend to go through when starting with modeling in software. It begins with euphoria, goes through all the way down to depression and (hopefully) ends with acceptation – acceptation that it’s just a model, not The Model.
Getting rid of these damn locks
For the last slot of the day I also have chosen the finance track and, again, it was a very good choice. Fortunately I was quite early as the room quickly became literally packed. The session about lock-free algorithms was presented by Martin Thompson (@mjpt777) and Michael Barker.
It started with a brief introduction to modern processor architectures. The key takeaway from this part is, the memory has a hierarchical structure and as the capacity increases, so does the access time. The other thing worth remembering is memory content is stored in cache in a structured form called lines and only one CPU core can claim a single cache line at a time.
Then speakers moved to explaining why locks are bad. This is pretty straightforward as the key problem is locks require kernel-level code to be executed in order to ensure atomicity. Switching between user mode and kernel mode is very costly comparing to arithmetic operations. Conclusion? Locks should be avoided at all cost when building high performance software.
It turns out that it is not as hard as people think to build a lock-free data structure like queue. In fact, Martin and Michael were able to fit the full code in two slides. The result was much faster than the classic version with locks but this was only the beginning as the code was missing a bit of ‘mechanical sympathy’ – it did not take into account how the processor works internally. How can we change this? Guys showed us a few very useful tricks:
- Division is a very costly operation. It turns out in some circumstances (number is o power of 2) it can be replaced with a simple bit operation
- Compilers tend to lay out class fields close to each other in memory which makes them end in same cache line. Even though each thread modifies its own value, cache line ownership is being transferred forth and back and core have to access memory to read the value
There were also other neat tricks shown which I do not remember now but when in need I can find them on Martin’s blog.