Note
*However, modern CPUs can also do a lot of things in parallel. Most CPUs are pipelined, meaning that the next instruction is loaded while the current one is executing. It might have a branch predictor that tries to figure out what instructions to load next.
The processor can also reorder instructions by using out-of-order execution if it believes it makes things faster this way without ‘asking’ or ‘telling’ the programmer or the OS, so you might not have any guarantee that A happens before B.
The CPU offloads some work to separate ‘coprocessors’ such as the FPU for floating-point calculations, leaving the main CPU ready to do other tasks et cetera.
As a high-level overview, it’s OK to model the CPU as operating in a synchronous manner, but for now, let’s just make a mental note that this is a model with some caveats that become especially important when talking about parallelism, synchronization primitives (such as mutexes and atomics), and the security of computers and operating systems.
Concurrency versus parallelism
Right off the bat, we’ll dive into this subject by defining what concurrency is. Since it is quite easy to confuse concurrent with parallel, we will try to make a clear distinction between the two from the get-go.
Important
Concurrency is about dealing with a lot of things at the same time.
Parallelism is about doing a lot of things at the same time.
We call the concept of progressing multiple tasks at the same time multitasking. There are two ways to multitask. One is by progressing tasks concurrently, but not at the same time. Another is to progress tasks at the exact same time in parallel. Figure 1.1 depicts the difference between the two scenarios:
Figure 1.1 – Multitasking two tasks
First, we need to agree on some definitions:
• Resource: This is something we need to be able to progress a task. Our resources are limited. This could be CPU time or memory.
• Task: This is a set of operations that requires some kind of resource to progress. A task must consist of several sub-operations.
• Parallel: This is something happening independently at the exact same time.
• Concurrent: These are tasks that are in progress at the same time, but not necessarily progressing simultaneously.
This is an important distinction. If two tasks are running concurrently, but are not running in parallel, they must be able to stop and resume their progress. We say that a task is interruptible if it allows for this kind of concurrency.