Static Optimization

When benchmarking C compilers, it is relatively common to convert FORTRAN benchmarks such as the Livermore Loops to C using the f2c translator. To preserve the semantics of FORTRAN, f2c converts all FORTRAN integer local variables to C static ints.

Many of these variables are used as loop induction variables. If the FORTRAN benchmarks had been written in C by a programmer, all of the loop induction variables would be declared with storage class auto, and most optimizing compilers would have little trouble keeping these variables in registers and performing other useful optimizations.

However, f2c maps these induction variables to storage class static, and many C compilers are unable to keep these variables in registers, even though the code does not otherwise inhibit keeping them in registers.

Compilers that are able to keep static int loop induction variables in registers can exhibit as much as 300% increase in performance on the Livermore Loops compared to compilers that keep these variables in memory.

Example:

In the function below, the variable i has been declared with storage class static. If the variable i is not assigned to a register for the life of the loop, then each iteration will require i to be fetched four times and stored once.

int a[SIZE];

void f (void)
{
  static int i;

  for (i = 0; i < SIZE; i++)
    a[i] = i;
}
  

In the function below, the storage class of i has been transformed from static to register. The semantics are the same, and the run-time performance is improved significantly.

int a[SIZE];

void f (void)
{
  register int i;

  for (i = 0; i < SIZE; i++)
    a[i] = i;
}