Loop unfolding

pri=-10 Stuart Lynne sl at van-bc.UUCP
Fri Sep 2 19:30:04 AEST 1988


In article <5612 at june.cs.washington.edu> rik at june.cs.washington.edu (Rik Littlefield) writes:
>All of the examples of loop unfolding recently discussed on the net have
>implemented just copying.  Several authors have suggested improving on
>the loop unfolding method by using a (pseudo-) standard routine like 
>'memcpy', or by declaring large structures that the compiler can generate
>good code for moving.
>
>I have seen at least three cases where loop unfolding was very productive
>but neither of the above suggestions seems to apply.  All were in time-
>critical production applications.

In the original Macintosh SCSI driver I was able to go from 3:1 interleave
on the SCSI disks to 2:1 simply by replacing Apple's SCSI manager with a
block copy with an unrolled loop, similiar to the Duff Device (only in 68000
asm). 

A recent example from a device driver. By unrolling the loop to check which
device had produced the interrupt we achieved the following:

  - could use absolute memory addresses instead of a variable
    - saved time not having to save a register to store the address
    - saved time not having to load the address into the var
  - no loop control variables required
    - no need to allocate a register, init or test it
  - loop overhead eliminated

The compiled code actually turned out to be almost the same size as the
orignal looped implementation, but significantly faster.


int (*cdsvint[4])() = { XXXXINT, XXXMINT, XXXFRINT, XXXEINT };
cdsintr( achan )
{
  register int intvec;   
  intvec = RMSPC( SUNBASE2+4, RWR2 );	/* required, grab intvec here	*/
  if ( (RMSPC( SUNBASE2, RWR0 ) & INTPEND ) ) { /* check pending 	*/
    (*cdsvint[(intvec >> 2)&0x3])( intvec&CHANA?2:3 );
    WMSPC( SUNBASE2, RWR0, EOIRST );	/* End of Interrupt Service	*/
    return( 1 );
  }
  intvec = RMSPC( SUNBASE+4, RWR2 );	/* required, grab intvec here	*/
  if ( (RMSPC( SUNBASE, RWR0 ) & INTPEND ) ) { /* check pending 	*/
    (*cdsvint[(intvec >> 2)&0x3])( intvec&CHANA?0:1 );
    WMSPC( SUNBASE, RWR0, EOIRST );	/* End of Interrupt Service	*/
    return( 1 );
  } 
  return( 0 );
}

-- 
Stuart.Lynne at wimsey.bc.ca {ubc-cs,uunet}!van-bc!sl     Vancouver,BC,604-937-7532



More information about the Comp.lang.c mailing list