Short code to determine compiler's number of registers

John Martin johnm at occam.ksr.com
Thu Jul 20 11:36:13 AEST 1989


In article <18603 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:
>
>... the way to find out how many registers the compiler will
>use on your code is to compile your code and count how many registers
>were used.  This is completely reliable, although not necessarily
>repeatable.  It is also likely to be a useless statistic.
>-- 
>In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
>Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris

All true.  For amusement's sake though, here is a C program that finds
out what register variables one can have by looking at their effect on
execution time, which presumably is why one might want to know in the
first place.  The following example works with gcc and cc on Sun
3's and 4's running SunOS 3.5, and should work on most UNIX machines
with little change.   As is frequently noted, timing routines are not
very portable across OS's; sorry about that.

On the systems I've tried ( Sun 3/75, 3/60, 3/140, 4/280 ) the
register-variable loops run about 2.2 - 2.5 times faster than the
memory-variable loops.  The SPARC is about twice as fast as a 3/75,
achieving about 1 million Hz for register loops.  For the curious the
register counts are:

    gcc : 10 registers on MC68020, 14 on SPARC.
Sun cc  :  6 registers on MC68020, 14 on SPARC.

Counting address registers, and finding whether address and integer
registers are separate or part of the same general register set, or
being used in a slick way by the compiler, are left as exercises to
the reader.  The answers will have some surprises -- for example, the
gcc MC68020 result of 10 integer registers is interesting, since an
MC68020 only has 8 data registers.  As Chris Torek says, the only way
to be sure what's happening is to look at the assembler.

/* showregs.c   How many registers will your compiler give you?
 *
 *  On a UNIX system:
 * 
 *       % cc showregs.c
 * _or_  % gcc -traditional showregs.c
 * _or_  % gcc -ansi showregs.c
 *
 * ( one flag or the other is needed to make PRINTLINE expand correctly)
 *
 *       % a.out > regs
 *       % graph -b -a -y 0 -g 1 < regs | plot
 */

#include <sys/time.h>
#include <signal.h>

#ifdef __STDC__
#define PRINTLINE(xx)   (void) printf( "%8u %s\n", xx, #xx)
#else          old-style macro substitution inside quotes
#define PRINTLINE(xx)    (void) printf( "%8u xx\n", xx) 
#endif

/* Execute a simple unrolled loop for a fixed time & count iterations.
 */
#define LOOPS(var)				 \
    var = 0;					 \
    timing = 1;					 \
    if ( setitimer( ITIMER_VIRTUAL, &itval, 0) ) \
	perror( "Starting timer");		 \
    while (timing) { var--; var++; var--; var++; var++; } \
    PRINTLINE(var)


unsigned timing;

int
vtalrmhandler()
{
    timing = 0;
    return 0;
}

int
main()
{
    register unsigned r01, r02, r03, r04, r05, r06, r07, r08, r09, r10,
                      r11, r12, r13, r14, r15, r16, r17, r18, r19, r20;
    struct itimerval itval;

    /* Set up to use the UNIX virtual timer for 200 milliseconds
     * of process time.
     */
    itval.it_value.tv_sec = 0;
    itval.it_value.tv_usec = 200*1000;
    itval.it_interval.tv_sec = itval.it_interval.tv_usec = 0;
    (void) signal( SIGVTALRM, vtalrmhandler);

    LOOPS(r01); LOOPS(r02); LOOPS(r03); LOOPS(r04); 
    LOOPS(r05); LOOPS(r06); LOOPS(r07); LOOPS(r08);
    LOOPS(r09); LOOPS(r10); LOOPS(r11); LOOPS(r12);
    LOOPS(r13); LOOPS(r14); LOOPS(r15); LOOPS(r16);
    LOOPS(r17); LOOPS(r18); LOOPS(r19); LOOPS(r20);
} /* end main */

/* EOF */

John H. Martin					harvard!ksr!johnm
Kendall Square Research Corporation		johnm at ksr.com
170 Tracer Lane
Waltham, MA 02154
"A creative economy is the fuel of magnificence." -- Emerson
Disclaimer:  My only organizationally-endorsed position is prone.



More information about the Comp.lang.c mailing list