The Challenges of Multicore Programming
In the basic sequential model of programming, a computer program's instructions are executed one at a time. The program is viewed as a recipe and each step is to be performed by the computer in the order and amount specified. The designer of the program breaks up the software into a collection of tasks. Each task is performed in a specified order, and each task stands in line and must wait its turn.In the sequential model, computer programs are setup in almost story form. The programs have a clear beginning, middle, and end. The designer or developer envisions each program as a simple linear progression of tasks. Not only must the tasks march in single file but the tasks are related in such a way that if the first task cannot complete its work for some reason then the second task may never start. Each task is made to wait on the result of previous task's work before it can execute. In the sequential model tasks are often serially interdependent. This means that A needs something from B and B needs something from C and C needs something from D and so on. If B fails for some reason, then C and D will never execute. In a sequential world, the developer is accustomed to designing the software to perform step 1 first, then step 2 then step 3. This 'one -at-time' model is so entrenched in the software design and development process that many programmers find it hard to see things any other way. The solution to every problem, the design of every algorithm, the layout of every data structure all rely on the computer accessing each instruction or piece of data one at a time.
This all changes when the software requirements include multithreading or multiprocessing components. When parallel processing is called for virtually every aspect of the software design and implementation is affected. The developer is faced with what we call the ten challenges of concurrency:
- Software decomposition into instructions or sets of tasks that need to execute simultaneously.
- Communication between two or more tasks that are executing in parallel.
- Concurrently accessing or updating data by two or more instructions or tasks.
- Identifying the relationships between concurrently executing pieces of tasks.
- Controlling resource contention when there is a many-to-one ratio between tasks and resource.
- Determining an optimum or acceptable number of units that need to execute in parallel.
- Documenting and communicating a software design that contains multiprocessing and multithreading.
- Creating a test environment that simulates the parallel processing requirements and conditions.
- Recreating a software exception or error in order to remove a software defect.
This is an excerpt from our book "Professional Multicore Programming: Design and Implementation for C++ Developers" Chapter 3, page 36.