Chapter Contents

Previous

Next
Optimization

Efficient Programming with the SAS/C Compiler

This section suggests several ways to write more efficient C code. By taking advantage of compiler features and the way the compiler generates code for certain C constructs, you can write programs that execute faster and more efficiently.


Using Leaf Functions

A leaf function is a function that calls no other functions. This property means that the function is always at the end of a calling sequence. The compiler can tell that a leaf function calls no other functions and takes advantage of this information. Instead of needing a fresh allocation of stack space, a leaf function uses a fixed area of storage in the CRAB for its automatic variables (as long as they do not exceed 128 bytes). This leads to a much more efficient entry and return sequence for these functions. You should make heavily used functions leaf functions where possible. Leaf functions are also known as DSA-less functions because no DSA is required.


Taking Advantage of Switch Optimizations

The compiler chooses from several possible algorithms when generating code for a switch statement. In some instances, the compiler can generate code for switch statements by using indexed tables with 1- or 2-byte entries. This ensures quick execution and also minimizes the amount of dataspace used.

For every switch encountered in the source file, the code generator analyzes the size and execution time that would result from each algorithm and chooses the best one. For switches with a small number of cases, one of the nonindexed methods is generally used since the overhead of the table lookup is not justified. However, for a large number of cases, an indexed algorithm is used for all but highly sparse switch statements.

Indexed algorithms require one table entry for each value in the switch range (the difference between the lowest and highest values in case statements). Therefore, it is advantageous to reduce the range of switch statements if possible because this reduces table space. If you have one or two case values that are very different from the others, you may want to test for them separately or handle them at the default label (which is not part of the range).


Optimization and Far Pointers

Most programs that use far pointers access a small number of address spaces. A typical design may use only the primary address space and one or two dataspaces. Because the optimizer and compiler cannot in general tell whether two far pointers reference the same address space, there may be a lot of unnecessary reloading of the access registers.

A technique that may lead to better generated code is to use only a few far pointers (one per secondary address space or dataspace) and then to use offsets rather than pointers to address objects in the dataspaces. For instance, in place of the following code:

   _ _far struct cb *lookup_user(char *);
   _ _far struct cb *userptr;
 
   userptr = lookup_user("fred");
   userptr->inuse = 1;

You could use the following equivalent code instead:

   extern _ _far char *user_data_space;
   int lookup_user(char *);
   int useroff;
 
   useroff = lookup_user("fred");
   ((_ _far struct cb *)(user_data_space + useroff))->inuse = 1;

This style allows the optimizer to recognize that the variable user_data_space is frequently accessed, and should have a register reserved for it. This may in turn mean that the ALET for the user dataspace will only need to be loaded from memory once during the execution of a particular function.

This style of coding can be made more readable by using the preprocessor, as shown in the following example:

#define contents(type, alet, offset) \
        ((_ _far type *)((alet) + (offset)))
#define offset(alet, addr) \
        (((_ _far char *) addr) - alet)
#define cb_contents(offset) \
        contents(struct cb, user_data_space, offset)
 
   extern _ _far char *user_data_space;
   int lookup_user(char *);
   int useroff;
 
   useroff = lookup_user("fred");
   cb_contents(useroff)->inuse = 1;


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.