If thrashing is a common occurrence, what keeps it from happening all the time? In theory, nothing! However, real programs that do useful work like computing taxes, simulating galaxy collisions, mapping out chromosomes and formatting text exhibit a very useful property: they do not access their memory spaces randomly. There is usually a pattern to how they reference both data memory and instruction memory.
Watching a program in action to count how many times it executes certain statements reveals that programs spend a lot of time in loops, and since most loops are small, programs spin around in a fairly small region of instruction memory. Occasionally, they call subroutines or jump to far-away regions of code. But at any given time, only a small region of instruction memory, or only several small regions, is being used. This is called the principle of locality, because the computer stays in a small, local region. When the region of memory is matched to the working set size, thrashing is unlikely.
The C program in Fig. 12.4.1 computes sin(x) by using a power series. The interior of the loop is executed many times, while the code before and after the loop is executed only once. The interior of the main for loop is called a hot spot.
#include <stdio.h> #include <stdlib.h> #define NUMTERMS 1 main() { double sum, x, xpower, fact; int i, sign, k; printf ("Enter angle in radians: "); scanf ("%lf", &x); sum = x; sign = -1; k = 3; fact = 1; xpower = x; for (i=1; i<NUMTERMS; i++) { +--------------------------------+ | xpower *= x * x; | | fact *= (k-1) * k; | | sum += sign * xpower / fact; | | k += 2; | | sign = -sign; | +--------------------------------+ } printf ("sin(%15.8f radians) = %15.8f\n", x, sum); }
Fig. 12.4.1: C program to compute sin(x); Hot spot is indicated by the outline
Data memory references similarly follow the principle of locality. Scalars that are used over and over again like loop counters and accumulators, such as sum in Fig. 12.4.1, obviously form regions that are hot spots. Also, large programs often manipulate data in one or two-dimensional arrays, and programs frequently move about in fairly small regions of these arrays before moving on to a different region. The principle of locality can thus be seen in action in both data memory and instruction memory.