Threads: Why and Why Not

CS 321 2007 Lecture, Dr. Lawlor

Why Threads?

Why do we even care about threads, or parallelism in general?  The reason is that computer technology is currently at something of a historical crossroads.  Since the 1950's, computers have gotten both bigger and bigger (more circuitry) and faster and faster (more computing per unit time).  Tons of stuff has changed--relays to vacuum tubes to silicon chips.  But strangely, a computer in 1956 was programmed in about the same way as a computer in 2006--for example, both of them could run ordinary programs written in Fortran. 

The main trick that's gotten us this far is "adding circuitry to speed up the CPU".  For example, look at the difference between a ripple carry addition circuit and a "lookahead" circuit.   Ripple carry is simple and small (meaning less circuits) but slow.  Lookahead is faster, but more complicated (more circuitry). 

As silicon technology allows you to produce more circuitry per dollar, a chip company has two choices--you can produce a cheaper product that performs the same, or you can produce a faster product that costs the same.  Intel would much rather sell 10 million $100 CPUs than 100 million $1 CPUs.  The mantra of CPU companies has thus been "more circuitry for more speed".

So far, "speed" has meant a combination of high clock rate and lots of work done per clock cycle. It used to be (back in the 386 era) that the CPU was clocked at about the same speed as the RAM (around 10MHz), and the CPU didn't really get much done every clock (a typical instruction would take 3 or 4 clock cycles to complete).  Both clock rates (MHz/GHz) and the amount of work accomplished per clock cycle (Instructions Per Clock, or IPC) have gone way up--today's machines run at GHz, and actually finish several instructions every clock cycle.  They require a huge amount of complexity to do this--huge caches, "branch prediction", "register renaming", "speculative execution", and so on.

And so for the last 50 years, this approach has worked pretty well.  Unfortunately, it's no longer sustainable.  The classic "too many GHz" CPU was the Pentium 4, which sacrificed everything for clock rate.  Even the Pentium 4 peaked at 3.8GHz, which is fast enough that the speed of light starts to become a serious problem--light travels 3 inches in 0.25 nanoseconds; electricity travels 2 inches, and the round trip time is 1 inch, which is about the size of a 25mm die! 

There is an old and useful solution to this problem--rather than use additional circuitry to make one CPU faster, make more CPUs.  People have been predicting this switch since at least the late 1980's (David Mitchell, The Transputer: The Time Is Now, 1989).  IBM first sold "dual core" PowerPC chips in 2005 (970MP: two CPUs, one piece of silicon).  AMD also released the dual-core Athlon X2 in 2005.  Intel finally introduced a dual-core chip with their Core Duo in early 2006, and in November 2006 released the four-core Core2 Quad.  They're busily working away at 16 and 32-CPU chips, since they understand the technology and economics underlying this trend.

The bottom line is that modern machines have multiple CPUs.  A single, single-threaded Fortran/C/C++/Java/C# program cannot take advantage of a multi-CPU machine. 

So you have several options:

The Problem With Threads--Example: THERAC-25 Race Condition

The THERAC-25was a piece of medical equipment capable of generating either a high-strength electron beam through a target to generate X-Rays, or scanning a much weaker raw electron beam over the surface of a cancer patient.  When you chose "Electron" mode, the software would begin this process:
When you chose "X-Ray" mode, the software would crank up the electron beam strength and insert the piece of metal used to generate X-Rays.  If you chose "Electron" mode (starting the calibration cycle) and then within 8 seconds went back and chose "X-Ray" mode, the end of the Electron mode setup would remove the crucial piece of metal needed for X-Ray mode, but then send a high-strength electron beam directly into the patient.  At least two people died as a direct result of this problem, and several more were permanently maimed.

The problem is just "simple" multithreaded locking--the two modes should have been exclusive, but because they were both running at the same time (directly from the keyboard interrupt) on the same machine they could interleave in a strange way.   Allow me to be more clear:

MULTITHREAD BUGS HAVE KILLED PEOPLE.

For goodness sake, don't let your software kill people!