About Concurrency and Parallelism in computing
Every so often something so exciting occurs in the computing industry, and more specifically in software development, and in this case in the Ruby language ecosystem, that it deserves writing about and sharing!
It’s multi-core age today. Concurrency is very important. With Ractor, along with Async Fiber, Ruby will be a real concurrent language. — Matz
Don’t know who Matz is? Read about him here.
Before we dig in to these two new concurrency models of programming in the Ruby languange, let’s talk about about modern computing…
Disclaimer: this is a very brief analysis, and it was mostly drawn up in an afternoon while searching for information (history) online. I expect there to be some inaccuracies. For a more in-depth and more accurate history, do your own research.
The 2000s - The hardware
Since about 2006, CPUs has been gaining an ability to run multiple processes (via cores) in parallel. Across all those cores, via the software layer, CPUs have also been able to run multiple threaded processes across all cores. It is important to understand the difference between cores vs threads, so go read more about it before you continue. It essentially boils down to cores are the actual hardware processing units which literally perform parallelism/concurrency by running software processes (programs) at the same time on each available core, whereas threads are virtual (software level) processing units that run your program across whatever core is available at any one moment.
If you’ve been following the personal computing world lately, you very well know about the relatively new Apple M1+ CPUs and how well they excell at running multiple tasks concurrently. While this is true for a number of reasons, one prominent reason is the many cores of this CPU (up to 10 at the time of this writing). The future of hardware, as it’s been for a long time in the works now (remember since 2006), is the use of many cores to achieve computational prowress. Soon enough we’ll have personal computers where the CPU contains 20 computational cores, 50 cores, 150 cores, and on and on. As a result, we need to make better use of these cores, otherwise they are just sitting there and all that computational prowress is for nothing (well, maybe for show haha).
The 2010s - The software
Naturally, software follows hardware. Up until recent time, with most programming languages you could only achive concurrent execution of a program at the software layer, via use of constructs like threads (much like the native multi-thread ability of the CPU). While these constructs made you use the CPU more effectively and effeciently, the whole time you were still running on only one core of the CPU (and in theory, the rest of the cores are sitting idle) Which is to say, the most common of programming languages did not or were not able to give the software developer the ability to write a program to make use of all the cores that a CPU contains at the same time. As an example of this, think of Java, the JVM, and the Thread feature.
In 2010 the first public version of Akka was released. It gained popularity and reached my perception of mass market from 2012 and on, see here as an indicator. In Akka, you find a implementation and introduction to the actor model of concurrency. The actor model of concurrency is a major shift in paradigm and technique to concurrency. This article does a great job at explaning the challenges of today’s common programming model, and how Akka and the actor system of concurrency became a better solution to take advantage of the modern day CPU (with it’s many cores!). The actor model of concurrency has gained so much validation and popularity, that other common programming languages are starting to pick it up, see this blog entry on Swift and in the next section we will go over Ruby’s take on concurrency.
The 2020s - The Ruby way to concurrent program
With the introduction of Ruby 3.0 in December of 2020, two new, much more modern (when compared to the Thread abstraction) ways to program concurrency were introduced: Fiber and Ractor. I’ve already covered these two new concurrency abstractions in previous blog posts, here and here, so I won’t be covering them in detail here. Needless to say, Ruby has joined modern computer languages in support of better ways to write computer programs with concurrency. I look forward to all of the practical ways we’ll be able to add concurrency to our software, and the perfomance gains of doing so.
In Summary
I am really excited about the future…
- Today’s hardware is starting to include tens of computing cores inside of the CPU, Apple’s M based CPUs is rejuvinating performance in the consumer PC world, and Intel while playing catch up and staying competitive with the 12th generation Core processors is doing the same on the Windows side of the market, particularly with Thread Director support in Windows 11.
- Today’s programming languages (and tools, think of all the Akka libraries and modules), are bringing software developers the right paradigm, techniques, and features to finally use up all of what today’s CPUs have in concurrent/parallel power. This, naturally, means that software developers will produce software that will be much more capable and faster (at least I have 😎).
- The Ruby language continues to stay relevant by introducing a developer happiness focused implementation of new standards and conventions in the software development industry. To along with that, the Ruby ecosystem also continues to stay relevant in it’s own by implemention of modern conventions and standars; a perfect example of this is Ruby on Rails with HTML-over-Websockets, read all about it here and here.