# 1.0 Shared Memory Preliminaries¶

Recall that a shared-memory multiprocessor is a type of computer where its compute units (or cores) all share the same main memory. In Section 0.5 we discussed how most computers today are shared-memory multiprocessors thanks to multicore CPUs. Virtually all modern Desktop and laptop computers, and even small single board computers such as the Raspberry Pi, contain multicore CPUs.

Before we can discuss what a thread is, we must first discuss what a process is. A process can be thought of as an abstraction of a running program. When you type a command into the command line and press Enter, the Bash shell launches a process associated with that program executable. Each process contains a copy of the code and data of the program executable, and its own allocation of the stack and heap.

A thread is a light-weight process. While each thread gets its own stack allocation, it shares the heap, code and data of the parent process. As a result, all the threads in a multi-threaded process can access a common pool of memory. This is why multithreading is commonly referred to as shared memory programming. A single-threaded process is also referred to as a serial process or program.

A multicore CPU allows multiple processes to execute simultaneously, or in parallel. While the terms concurrency and parallel are related, it is useful to think of concurrency as a software/OS-level concept, while parallel as a hardware/execution concept. A multi-threaded program, while capable of parallel execution, runs concurrently on a system with only a single CPU core.

The primary goal of creating multithreaded programs is to decrease the speed of a program’s execution. In a program that is perfectly parallelizable (that is, all components are paralleizable), it is usually possible to distribute the work associated with a program equally among all the threads. For a program $$p$$ whose work is equally distributed among $$t$$ threads, it will take roughly $$p/t$$ time, if executed on $$t$$ cores.