Check out the new USENIX Web site. next up previous
Next: JavaAnyone? Up: Performance Previous: Smaller is Better

Link-time Efficiency

After all the compilation units are compiled, the program must be linked together with the run time library to create a single executable. On conventional operating systems, there are shared objects to be linked to, and the kernel to be made available. In a kernel-based operating system the common functions are placed in a protected kernel that all the applications share.

In an embedded environment, where there is only one application, the kernel is not being shared so its size should be included as part of the cost of the application. uCR is not kernelized, it is presented as a library that the linker uses to resolve symbols. Only the parts of uCR that are explicitly used are allocated space in the final image.

This is an example program, linked with uCR, that has only an empty main and the code necessary to enable all the devices on a Picture Elements ISE board. The text section includes executable code and constants and can be placed in ROM. The bss section is large because it contains generous stack space (10K) for the main thread.

text    data    bss     dec   filename
3520    1232    10664   15416 file.exe

The following is the same program compiled for Linux/SPARC. The stack space is not included in the totals, nor is the linux kernel itself or any of the 4 shared objects that this image links to.

text    data    bss     dec  filename
2688    2575    8       5271 a.out

Ignore the bss sections (mostly stack space in file.exe) and the linux image is about the same size. The linux image is for sparc whereas the uCR image is for i960 so the differences may easily be due to instruction set constraints.

What is significant about this example is that the entire uCR image takes up no more space then an image linked to run in an environment that has several megabytes of uncounted resources in the host kernel and shared objects. These resources provide a very important value in the case of Linux, but none of them are of interest in an embedded target.

As the program becomes more interesting, the uCR image sizes naturally increase. For example, the following numbers apply to a program that has included a debugger interface and code to drive a PCI bus interface, along with an implementation of a channel protocol that communicates with a driver on a host computer. In this image, 16K of buffer space is included in the bss number, along with the main stack.

text    data    bss     dec   filename
12544   2824    27284   42652 file.exe

The advantage of placing the uCR infrastructure in a library is that only the parts actually used are brought into the image. This can include individual methods of a class (those that are not inlined). A kernel image, on the other hand, must be included all at once or not at all.


next up previous
Next: JavaAnyone? Up: Performance Previous: Smaller is Better

Stephen Williams
Sun May 4 15:28:26 PDT 1997