Address:
Email:
Many compiler options can have an adverse affect on a code. Most notably, various levels of optimization can "break" a code, such that the program gives erroneous results. One option is to compile for the lowest common denominator. The other option is to identify which routines are adversely affected. The local utility, bchop performs a binary chop between object files in two directories (./good and ./bad), compares the output and isolates which object files are causing the differences in output. This helps isolate problems due to changing compiler or preprocessor options. The number of runs performed is approximately 2*E*log2(N) where N is the number of object files and E is the number of object modules causing errors. This utility, bchop, is similar to CRI's atchop for isolating multitasking problems.
In another scenario, the code is debugged, optimized, and verified. Two or three years pass by, the system compiler is upgraded several times as well as the operating system; or the code is taken to a similar, but not quite identical system. Recompiling with full optimization now results in erroneous results that are hard to trace down. One option is to recompile with optimization turned off, but at a substantial performance penalty.
The ideal solution is to find which compilation units, as well as the
trouble spots within them, are adversely affected by compiler
optimization levels. In the absence of an ideal solution
bchop can at least find which compilation units are thus affected.
This method then favors modular programming such that each and every
subroutine or function is isolated into it's own compilation unit.
Theory
What little theory there is in bchop is summarized by the
phrase "binary decomposition"[1]
or sometimes refered to as
"interval halving".
The procedure is to group half of the compilation units (or object files)
into one set and the remaining objects into
another set. The first set will comprise object files collected
from the object files giving "bad" results and the remainder
will be collected from the object files giving "good" results.
In practice, the "bad" object files are those compiled with
optimization turned on and the "good" object files are compiled
with debugging options which usually inhibit optimization.
The object files are compiled once only by the user and
placed into directories named ./bad and ./good respectively.
The "good" and "bad" object files are linked together,
the binary is then executed and the output is compared to an accepted
"good" output.
If the output compares favorably then those object files in the
"bad" set are tagged as acceptable and are no longer considered
for further testing. On the other hand,
if the output shows a difference the set of "bad" object files
is further divided in half and the above procedure is repeated.
Each object file represents
an endpoint in a binary tree, which takes
O(logN) steps to traverse.
Practice
The above algorithm describes a depth first search. For practical
reasons bchop does a lateral search proceeding from the root
downwards. The object files are numbered and
selected into sets according to the least significant bits.
The first level corresponds to an odd/even split. The odd numbered
set of object files are tested, then the even numbered set is tested.
If one set is deemed acceptable the rest of the object files are
"reshuffled" (i.e. reordered and renumbered), and the
procedure is repeated with the reduced set.
However, if both sets yield incorrect results the collection of
object files is split into fourths, and each fourth is tested.
If there is still no resolution the collection of object files is split into
eighths, and so forth.
See Figure 1 for a simple example of how the sets are selected.
When any of the sets contain only one element then bchop goes into a one-by-one comparison mode where each object file is tested individually. It will be shown later that one-by-one testing is more efficient for small samples or when the ratio of "bad" to "good" object files is large.
Figure 2: A bchop binary decomposition where X represents a "bad" object file. Red represents tests with errant results, and pink for tests with correct results. Further testing is no longer performed on object files that give correct results.
When more than one errant object file exists, say E of them, the number of trials can be shown to be less than or equal to 2Elog2(N). Refer to Figure 3 for an example of two "bad" object files out of 16. Since both the errant object files lie in the same half of the ordering at the second level of testing both tests indicate incorrect results, thus requiring the sample to be more finely divided and retested.
Figure 3: A bchop binary decomposition where the X's represents "bad" object files, see Figure 2 for details regarding the color scheme. The two "bad" object files lie in the same half of the ordering.
A more extensive test was performed with up to 140 object files and up to three errors randomly scattered among them. The test was repeated three times for each configuration. The results are plotted in Figure 4. There is definitely good agreement with the number of trials performed and the theoretical upper limit. However, for small numbers of object files (generally less than 15) it is usually more efficient to perform a one-by-one comparison test unless it is known before hand that the number of errant object files is very small. The actual number of trials performed is highly dependent on errant object file location in the ordered list. If, for example, they all fell into the same sampling octant then the number of trials performed would be comparable to a task an eighth of the size. The larger the number of "bad" object files, the more likely they will demonstrate clustering.
Figure 4: bchop results for 1,2, and 3 "bad" object files in a large number of object files. The curved line represents the number of trials needed to perform a one-by-one comparison test. The upper limit for the number of trials is given by 2Elog2(N), where N is the total number of object files and E is the number of "bad" object files. The straight lines represent this upper limit given for E=3,2, and 1 from the top down respectively.
* bchop is quite flexible in allowing the user to include a custom script for output comparison. The output can be filtered to extract only the relevant data, skipping date and time fields which by their very nature will vary from run to run.