Live data from Hacker News

The free lunch is over: a fundamental turn toward concurrency in software (2005)

gotw.ca

11–20 of 101 posts

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#11
post #5

Earlier quoted context omitted.

I will go with lack of education as main issue.

Lack of real need I think. Most of the computers in the world are either dedicated embedded controllers or end user devices. Concurrency in embedded controllers is pretty much an ordinary thing and has been since the days of the 6502/Z80/8080. For end user devices the kind of concurrency that matters to the end user is also not extraordinary, plenty of things happen in the background when one is browsing, word proces…

> So that leaves concurrency inside applications and that just isn't something that affects most of the end users. There really isn't much for a word processor to actually do while the user is thinking about which key to press so it can do those few things that there was not time for during the keypress.

This obviously depends on the application. Whenever you need to wait for an app to finish an operation that is not related to I/O, there is some potential for improvement. If a CPU-bound operation makes you wait for more than, say, a minute, it's almost definitely a candidate for optimization. Whether multithreading is a good solution or not depends on each case - when you need to communicate/lock a lot, it might not make sense. A good part of the solution is figuring out if it makes sense, how to partition the work etc.; the other part of this hard work is implementing and debugging it.

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#12
post #5

Earlier quoted context omitted.

I will go with lack of education as main issue.

Lack of real need I think. Most of the computers in the world are either dedicated embedded controllers or end user devices. Concurrency in embedded controllers is pretty much an ordinary thing and has been since the days of the 6502/Z80/8080. For end user devices the kind of concurrency that matters to the end user is also not extraordinary, plenty of things happen in the background when one is browsing, word proces…

Interesting that you mention Wirth, since all his programming languages from Modula-2 onwards do expose concurrency and paralelism.

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#13

People having been saying this for decades and while it's true, concurrency is still widely regarded as 'too hard'. I'm not sure if this is justified (e.g. concurrency is inherently too hard to be viable), or due to the lack of tooling/conventions/education.

The rise of async programming in backend web dev is making some people even more confused about models. For instance, many senior engineers out there don't understand the difference between sync multithreaded and async single threaded.

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#17
post #5

Earlier quoted context omitted.

I will go with lack of education as main issue.

Memory models are subtle. Temporal reasoning in context of h/w, e.g. multi-core coherence, and language runtime MM is non-trivial. So there is a baseline level of difficulty baked into the domain. Education certainly is necessary, but here can only inform of what needs to be considered, known pitfalls, patterns of concurrency, etc. As to OP, well it better be viable, because we certainly need to deal with it. So bett…

> Temporal reasoning in context of h/w, e.g. multi-core coherence, and language runtime MM is non-trivial.

Don’t OSs expose that in the sense you can pin a threads to closest cores according to the memory access you need?

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#19

People having been saying this for decades and while it's true, concurrency is still widely regarded as 'too hard'. I'm not sure if this is justified (e.g. concurrency is inherently too hard to be viable), or due to the lack of tooling/conventions/education.

My 5 cents would be wrong abstraction and wrong tooling, let me elaborate a bit of them:

- Current abstractions are mostly based on POSIX threads and C++/Java memory models. I think they are poorly representing what is actually happening in hardware. For example Acquire barrier in C++ makes it really hard to understand that in hardware it equals to a flush of invalidation queue of the core, to sanity check your understanding try answering the question "do you need memory barriers if you have multithreaded application (2+ threads) running a lock-free algorithm on a single core?", correct answer is no, because same core always sees it's own writes as they would happen in program order, even if OOO pipeline would reorder them. Or threads, they seem to be an entity that can either run or stop, but in hardware there are no threads, CPU just jumps to a different point in memory (albeit through rings 3->0->3). Heck even whole memory allocation story, we have generations of developers thinking about memory allocation and it's safety, yet hardware doesn't have that concept at all, memory range mapping concept would be the closest to what MMU actually does. Hence the impedance mismatch between hardware and current low level abstractions created a lot of developers who "know" how all of this works but doesn't actually know, and a bit afraid to crush through layers. I want more engineers to not be afraid and be comfortable with all low level bits even if they would never touch them, because one day you will find a bug like broken compare-exchange implementation in LLVM or similar.

- Tooling is way off, the main problem with multithreading is that it's all "in runtime" and dynamic, for example if I'm making a lockfree hashmap, the only way for me to get into the edgecases of my algorithm (like two threads trying to acquire same token or something) is to run a bruteforce test between multiple threads and wait until it actually happens. Bruteforce-test-development scales very poorly, and testing something like consensus algorithms for hundreds of threads is just a nightmare of complexity of test fixtures involved. Then you get into ok, so how much testing is enough? How do you measure coverage? Lines of code? Branches? Threads-per-line? When are you sure that your algorithm is correct? Don't get me wrong, I've seen it multiple times, simple 100 lines of code passing tons of reviews only for me to find a race condition (algorithmical one) half a year later, and now it's deployed everywhere and very costly to fix. Another way would be to skip all of that and start modeling your algorithms first, TLA+ is one of the better tools for that out there, prove that your model is correct, and then implement it. Using something like TLA+ can make your multithreading coding a breeze in any language.

And probably absence of transactional memory also contributes greatly, passing 8 or 16 bytes around atomically is easy, but try 24 or 32? Now you need to build out an insanely complicated algorithm that involves a lot of mathematics just to prove that it's correct.

Re: The free lunch is over: a fundamental turn toward concurrency in software (2005)

#20

People having been saying this for decades and while it's true, concurrency is still widely regarded as 'too hard'. I'm not sure if this is justified (e.g. concurrency is inherently too hard to be viable), or due to the lack of tooling/conventions/education.

I see a lot of potential in pipeline concurrency, as seen in dataflow (DF) and flow-based programming (FBP). That is, modeling computation as pipelines where one component sends data to the next component via message passing. As long as there is enough data it will be possible for multiple components in the chain to work concurrently.

The benefits are that no other synchronization is needed than the data sent between processes, and race conditions are ruled out as long as only one process is allowed to process a data item at a time (this is the rule in FBP).

The main blockers I think is that it requires quite a rethink of the architecture of software. I see this rethink happening in larger, especially distributed systems, which are modeled a lot around these principles already, using systems such as Kafka and message queues to communicate, which more or less forces people to model computations around the data flow.

I think the same could happen inside monolithic applications too, with the right tooling. The concurrency primitives in Go are superbly suited to this in my experience, given that you work with the right paradigm, which I've been writing about before [1, 2], and started making a micro-unframework for [3] (though the latter one will be possible to make so much nicer after we get generics in Go).

But then, I also think there are some lessons to be learned about the right granularity for processes and data in the pipeline. Due to the overhead of message passing, it will not make sense performance-wise to use dataflow for the very finest-grain data.

Perhaps this in a sense parallels what we see with distributed computing, where there is a certain breaking point before which it isn't really worth it to go with distributed computing, because of all the overhead, both performance-wise and complexity-wise.

[1] https://blog.gopheracademy.com/composable-pipelines-pattern/

[2] https://blog.gopheracademy.com/advent-2015/composable-pipeli...

[3] https://flowbase.org

Post reply on HN