Previous Table of Contents Next


8.2 TECHNIQUES FOR IMPROVING PROGRAM PERFORMANCE

The three common techniques of program optimization are code optimization, I/O optimization, and paging optimization. The code optimization consists of finding the dynamic frequency of execution of various program modules and optimizing the code of most frequently used modules. The I/O optimization usually consists of combining several I/O requests into larger records, changing the file access method, and caching or prefetching data. Paging optimization consists of observing the page reference pattern and reorganizing program segments so that the paging activity is minimized. Box 8.1 lists a number of techniques for writing high-performance programs and for improving the performance of existing programs.

8.3 ACCOUNTING LOGS

Accounting logs, although not primarily developed for monitoring, are classified as software monitors because they provide useful information about system usage and performance, and they can often be used as substitutes for monitors. Before starting to develop a monitor, one should look at the logging facilities built into the system. Often, a new monitor is not necessary.

The main advantage of accounting logs is that they are built in. No extra effort is required to develop them. Most of the data is already collected during normal operation. The overhead is generally small, so data collection can be performed for long periods of time. Further, the data reflects real-system usage.

The main disadvantage of accounting logs is that the log analysis programs are not usually supplied. Since the analysis needs are different in each case, most systems convert the log into a generally readable format or produce an overall summary. Additional analysis programs have to be written by the analysts themselves. A general-purpose statistical analysis package may be useful for detailed analysis.

The data in the logs may not be at the desired level of granularity. For example, a distribution of I/O sizes is generally not available from the logs. Only the total number of blocks read or written may be available. Further, often the only resource usages that are recorded are those charged to the user. For example, if terminal I/O’s are not charged, a record of them may not be kept in the logs.

The accuracy of logs is also low. The resource usage not chargeable to any particular user is distributed either evenly among or randomly to users. For example, CPU time spent in servicing interrupts may be charged to the user active at the time of the interrupt, even though the interrupt may be for another user not currently active.

Box 8.1 Techniques for Improving Program Performance

1.  Optimize the common case. The most frequently used path should also be the most efficient. A procedure should handle all cases correctly and common cases efficiently.
2.  Arrange a series of IF statements so that the most likely value is tested first.
3.  Arrange a series of AND conditions so that the condition most likely to fail is tested first.
4.  Arrange entries in a table so that the most frequently sought values are the first to be compared.
5.  Structure the main line of the program so that it contains the most frequent path of the program. Errors and exceptions should be handled separately.
6.  Question the necessity of each instruction in the main (time-critical or most frequent) path of the code.
7.  Trade memory space for processor time wherever possible. If a function is computed more than once, compute it once and store the result. Some functions with parameters can be replaced by a table of precomputed values.
8.  Use hints. Keeping a fast but possibly inaccurate hint along with a slow but robust algorithm may save time in most cases.
9.  Cache the data that is accessed often. However, one must ensure that there is sufficient locality before using caches.
10.  Unroll short loops. Save the cost of modifying and testing loop indexes.
11.  Replace searches by direct indexing, wherever possible. In some cases, this may require more space than minimum.
12.  Use the same size for data fields that need to be compared or added together.
13.  Use the full word widths of the computer to evaluate expressions. For example, use 32 bits on a 32-bit computer even if you need only 31.
14.  Align data fields on word boundaries, wherever possible.
15.  Evaluate items only when needed, particularly if it is likely that it will not be needed.
16.  Initialize data areas during run time only when used. Wherever possible, the values should be initialized at the compile time.
17.  Use algebraic identities to simplify conditional expressions.
18.  Replace threshold tests on monotone (continuously nondecreasing or continuously nonincreasing) functions by tests on their parameters, thereby avoiding the evaluation of the function.
19.  Evaluate variables not changing in a loop before entering the loop.
20.  Combine two nearby loops if they use the same set of conditions.
21.  Use shifts in place of multiplication and division by powers of 2.
22.  Keep the code simple. Simpler programs are more efficient.
23.  Block I/O requests together to reduce the number of I/O operations.
24.  Preload small disk files into tables in memory.
25.  Use multiple buffers for files to allow prefetching.
26.  Link the most frequently used procedures together to maximize the locality of reference.
27.  Reference data in the order stored. Arrays stored by columns should be referenced by columns.
28.  Store data elements that are used concurrently together.
29.  Store subroutines in sequence so that calling and called subroutines will be loaded together.
30.  Align I/O buffers to page boundaries.
31.  Open files that are used together in sequence so that buffers will be located together.
32.  Pass simple subroutine arguments by value rather than by reference, wherever possible.
33.  Pass large arrays and other data structures to subroutines by reference rather than value.
34.  Separate read-only code areas from read-write data areas to minimize the number of page-writes.


Previous Table of Contents Next

Copyright © John Wiley & Sons, Inc.