To indicate the relative merits of some of the above code generation techniques, timing results for the following simple benchmarks are provided:
Measurements were made on a Sun Sparcstation 2 with 64 megabytes of main memory. The native code generation experiments were conducted using a Napier88 system based on a single user, page based (CASPER ) object store held on a local disk. Computation-intensive benchmarks are used for two reasons. Firstly, the performance characteristics of the persistent object store cannot significantly affect the results. Secondly, a C implementation of the benchmarks can be used to give an upper bound on our performance expectations.
Figure 6: Performance increase relative to interpreted system.
The graph in Figure 6 shows the speedup relative to the CASPER PAM achieved by the incremental application of the code generation techniques. For comparison the graph includes the performance of the benchmarks written in GNU C when optimised and un-optimised. Note that procedure calls are relatively infrequent in the quicksort algorithm; hence the flat spot on the quicksort curve.
One drawback of the generated code is its size. It is only fair to expect that native code be significantly larger than PAM code, since PAM instructions can describe complex operations in a single byte, while the smallest machine instruction available on the SPARC architecture occupies four bytes.
Code files containing native code can exceed the size of their PAM code counterparts by a factor of ten, or more. As the graph in Figure 7 illustrates, code file sizes have varied significantly during our experiments with code generation techniques.
Figure 7: Sizes of the code files for the benchmark programs (kb).
The other drawback is that compilation to native code is relatively slow. The native code compiler takes between three and fifteen times as long as the PAM-code generating compiler on which it is based. For instance, compiling the Dhrystone benchmark into PAM code takes about 10 seconds; compiling it with the native code compiler takes about 35 seconds, or 105 seconds with GNU C optimisation level 2.
The extra time is spent almost entirely in GNU CC. This is not surprising, since large amounts of C code are generated. Compiling Dhrystone produces 100K of macros which are expanded into 480K of C source by the pre-processor.
We have endeavoured to reduce code size and compilation time by making the code generation patterns as simple as possible, factoring out common segments of code into new run-time support calls.