May 2006

Aggregate Optimization and Tuning III: Results

In the previous texts of this series, building four key software components was done to see if it would yield any results. These were:

  • A Linux kernel
  • A full Perl distribution
  • The bash shell
  • The GNU Compiler Collection (gcc)

The kernel was covered again in the second part of the series. In this last installment, some small tests and the results.

Tests

The Perl and GCC test were relatively simple. A small program was devised for each that does the following:

        reads in a loop count

        calls a recursive division function that divides two random integers
        until the loop equals zero

C Program Listing - rdiv.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void rdiv (int count, int top, int bottom)
{
        int result = 0;

        if (count > 0) {
                result = (top/bottom);
                count = (count - 1); // we do this bc --foo is not to be trusted
                        rdiv(count, rand(), rand());
        } 
}

int main(int argc, char *argv[]) 
{
        int count;

        count = atoi(argv[1]);

        rdiv(count, rand(), rand());

        return 0;
}

Perl Script Listing - rdiv.pl

#!/usr/bin/env perl
sub divide {
        my ($cnt, $divisor, $dividend) = @_;
        my $garbage = 0; # placeholder for the division result

        if ($cnt > 0) {
                --$cnt;
                $garbage = ($divisor / $dividend);
        } else {
                return;
        }

        divide($cnt, $divisor, $dividend);
}

# Main
my $initial_count = $ARGV[0];
my $MAX_INT = 32784;
divide($initial_count, int(rand($MAX_INT)), int(rand($MAX_INT)));

Bash Script Listing - gcd.sh

ARGS=2
E_BADARGS=65

if [ $# -ne "$ARGS" ]
then
  echo "Usage: `basename $0` first-number second-number"
  exit $E_BADARGS
fi

gcd ()
{

  dividend=$1
  divisor=$2
           

  remainder=1

  until [ "$remainder" -eq 0 ]
  do
    let "remainder = $dividend % $divisor"
    dividend=$divisor            
  done 

}     

gcd $1 $2

echo; echo "GCD of $1 and $2 = $dividend"; echo

exit 0

The bash test uses a script borrowed from the advanced bash guide which finds the greatest common denominator of two numbers. By feeding the GCD script unusual and large numbers a measurement could be obtained. Each test ran thirty times, however, only three output examples for each are:

Regular GCC

real    0m0.062s
user    0m0.040s
sys     0m0.020s

real    0m0.062s
user    0m0.028s
sys     0m0.032s

real    0m0.065s
user    0m0.044s
sys     0m0.020s

Optimized GCC

real    0m0.057s
user    0m0.028s
sys     0m0.028s

real    0m0.064s
user    0m0.044s
sys     0m0.020s

real    0m0.062s
user    0m0.044s
sys     0m0.016s

Regular bash

real    0m0.019s
user    0m0.016s
sys     0m0.004s

real    0m0.019s
user    0m0.016s
sys     0m0.004s

real    0m0.019s
user    0m0.012s
sys     0m0.004s

Optimized bash

real    0m0.019s
user    0m0.020s
sys     0m0.000s

real    0m0.019s
user    0m0.020s
sys     0m0.000s

real    0m0.019s
user    0m0.016s
sys     0m0.004s

Regular Perl

real    0m1.360s
user    0m1.100s
sys     0m0.248s

real    0m1.357s
user    0m1.112s
sys     0m0.224s

real    0m1.355s
user    0m1.068s
sys     0m0.272s

Optimized Perl

real    0m1.176s
user    0m0.960s
sys     0m0.200s

real    0m1.178s
user    0m0.964s
sys     0m0.204s

real    0m1.172s
user    0m0.952s
sys     0m0.204s

Kernel Results

The kernel itself did not seem to be a lot faster. Outside of full blown profiling or code injection, there was no simple way to test it. On the positive side the kernel compiled and packaged a lot faster using the optimized GCC compiler.

Interpreting the Results

First, the bash shell had no marginal difference, the results were nearly identical regardless of the combinations of numbers (or the test for that matter).

The next more interesting item is the Perl results, which shows a definite speed improvement with larger requirements. A larger virtual memory space makes sense when considering that optimization generally does tricks like loop unwinding that naturally need more code space.

The most surprising is GCC. While it does not show with a small program, when compiling a kernel with the optimized compiler, the compile finished in nearly 1/2 the time.

Summary

While some components such as shells may not directly benefit from optimization, even this experiment which is small in relation to what could be tested, shows that larger software systems such as a kernel or OS build can benefit from just small optimization strategies.