Coverage Analysis

Computer engineers often need to know how frequently each instruction in a program is executed. This information may be used to determine which portions of the program have been executed and tested by the test data or which portions of the program consume the most CPU time. It may also be used to determine which instruction types are used more often and design better computers accordingly, more efficient for the frequent instruction types.

This information may be obtained by running programs on a computer while a logic analyzer connects to the instruction address bus and determines the number of times each instruction in the program is executed. Using the debugging information, which tells to which line number corresponds each address, it is also possible to determine the number of times each line number (statement) is executed.

The debugger may be used to generate an execution trace. The trace can thereafter be processed to count the number of times each instruction or statement is executed. However, this is usually quite slow.

Another method is to have the compiler, or assembler, insert instructions that count the number of times each program section is executed. Since sequences of instructions without intervening branch or entry point are always executed together, a single counter is sufficient for each such sequence. At the end of the program execution, the final counts may be printed in a file. The time overhead of this method is small since it only requires one increment operation per instruction sequence.

There are cases where the assembly or high level source code is not available and using special purpose hardware like a logic analyzer is not convenient. Fortunately, there are some tools that read an executable file and output a modified executable file with instructions inserted to count the number of times each instruction is executed.

While frequency counts are an indication of CPU time usage, they are not very accurate. Indeed, they do not tell the number of cycles spent on each instruction (which may be hard to compute on a superscalar pipelined processor) or the effect of waiting for the cache or virtual memory. The frequency counts may be sufficient to detect obvious performance bugs but other tools may offer greater accuracy.


Copyright 1995 Michel Dagenais, dagenais@vlsi.polymtl.ca, Wed Mar 8 14:41:03 EST 1995