[comp.sys.transputer] How busy is your Transputer ?

RABAGLIATIA@isnet.inmos.com (10/24/90)

The following is something I put together some time ago to
assist in profiling multi-Transputer systems.

Cheers,  Andy Rabagliati    EMAIL:- rabagliatia@isnet.inmos.COM



                     SUPERVISOR Procedure
                     --------------------

The purpose of this procedure is to find out  how  "busy"  the 
Transputer is.  

It returns an INTeger value, the percentage utilization of the 
CPU.

To use it  -  this  procedure  is  run  in  parallel  with  an 
application, and communicates down two channels, COMMAND (into 
SUPERVISOR) and REPLY (out of SUPERVISOR), both CHAN OF INT.  

There  are  two  phases  -  a  CALIBRATION  phase,  where  the 
procedure  measures  how  fast the scheduling mechanism is - a 
function of processor speed  and  whether  it  is  running  in 
internal  or  external  RAM.  This  MUST be run when ALL OTHER 
PROCESSES are waiting. When SUPERVISOR starts up, it waits for 
a signal (an INT) down the COMMAND channel, to signify that it 
can start calibration.  It then tells when it is done (approx.  
1.6 msec later) by outputting an INT down RESULT.  

The  second  phase is the TIMING phase.  During this phase the 
COMMAND channel recognises two values -

 start (0) This marks the start of the measured period.  

 read  (1) This  tells  the  SUPERVISOR   to   calculate   the 
           percentage utilisation since the last start message 
           is  received,  and  send  the result down the REPLY 
           channel.  

The REPLY channel returns a single integer when prompted to do 
so by read. It is the percentage utilisation of the machine.  

Some CAVEATs :-

SUPERVISOR MUST be run at low priority.

SUPERVISOR never terminates.  This is done for simplicity,  so 
it does not require an ALT in the busy loop.  

SUPERVISOR cannot be used to time periods  longer  than  about 
2000  seconds.  Otherwise  there is an integer overflow in the 
percentage calculation. In the interests of keeping SUPERVISOR 
simple,  all calculation was done in integer,  or the accuracy 
of the calibration period can be altered.  As a rule of thumb, 
the  calibration  period  (in  Ticks) multiplied by the timing 
period  (in  seconds)  cannot  be  greater  than  50,000.   If 
required, it can be rewritten using floating point.  

SUPERVISOR only works on 32 Bit machines,  for the same reason 
as above, and also timer range.  

SUPERVISOR must have Usage Checking switched off  to  compile.  
Again,  this  is  done  to save having to do an ALT.  However, 
SUPERVISOR can be separately compiled.  
   
                   HOW DOES IT WORK ?
                      ------------------

It measures busyness does by measuring the converse - how idle 
the machine is.  A process within  SUPERVISOR  reads  the  (Hi 
priority)  clock.  It  then  puts itself on the back of the Lo 
priority process list.  When it gets to the  front  again,  it 
reads  the  time again - and finds out how long it took to get 
around again.  If it is less than a certain number of Ticks  - 
20  seems  about  right  - SUPERVISOR must be the only process 
active. In this instance, it increments an Idle counter.  

It times the speed of the loop during the  calibration  phase.  
When  asked  to  time  a  period,  it times the length of that 
period,  and the rate of increase in  the  Idle  counter,  and 
compares  that to the calibration loop,  multiplies it by 100, 
and outputs a percentage.  














--{{{  SUPERVISOR (CHAN command, result)
PROC SUPERVISOR(CHAN OF INT command, result)
  VAL start IS 0 :
  VAL read IS 1 :
  VAL period IS 25 :
  INT Idle, Calibrate :
  [130]INT trash :
  PAR
    --{{{  Idle counter
    INT now, then :
    SEQ
      Idle := 0
      WHILE TRUE
        SEQ
          PRI PAR
            TIMER TIME :
            TIME ? now
            SKIP
          IF
            (now MINUS then) < 20
              Idle := Idle+1
            TRUE
              SKIP
          then := now
    --}}}
    SEQ
      command ? Calibrate
      --{{{  wait a second - calibrate idlers
      INT now :
      TIMER TIME :
      SEQ
        Idle := 0
        TIME ? now
        TIME ? AFTER now PLUS period
        Calibrate := Idle
      --}}}
      result ! Calibrate
      INT begin :
      TIMER TIME :
      WHILE TRUE
        INT signal :
        SEQ
          command ? signal
          IF
            --{{{  start
            signal = 0
              SEQ
                Idle := 0
                TIME ? begin
            --}}}
            --{{{  read
            signal = 1
              INT finish, Idle.count :
              INT temp :
              SEQ
                Idle.count := Idle
                TIME ? finish
                VAL elapsed IS finish MINUS begin :
                temp := (Calibrate * elapsed) / period
                IF
                  temp <> 0
                    temp := ((temp - Idle.count) * 100) / temp
                  TRUE
                    SKIP
                result ! temp
            --}}}
:
--}}}