Logo Search packages:      
Sourcecode: u++ version File versions

Bench.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Peter A. Buhr 1994
// 
// Bench.cc -- Timing benchmarks for the basic features in uC++
// 
// Author           : Peter A. Buhr
// Created On       : Thu Feb 15 22:03:16 1990
// Last Modified By : Peter A. Buhr
// Last Modified On : Fri Aug 27 07:57:43 2004
// Update Count     : 349
// 

#include <uC++.h>
#include <uIOStream.h>

unsigned int uDefaultPreemption() {
    return 10;
} // uDefaultPreemption
 
#include "Time.h"

//=======================================
// time class
//=======================================

class ClassDummy {
  public:
    int bidirectional( int a, int, int, int ) {
      return a;
    } // ClassDummy::bidirectional
}; // ClassDummy

void BlockClassCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      ClassDummy dummy __attribute__(( unused ));
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // BlockClassCreateDelete

void DynamicClassCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      ClassDummy *dummy = new ClassDummy;
      delete dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // DynamicClassCreateDelete

void ClassBidirectional( int N ) {
    int StartTime, EndTime;
    ClassDummy dummy;
    int i, rv;

    StartTime = Time();
    for ( i = 0; i < N; i += 1 ) {
      rv = dummy.bidirectional( 1, 2, 3, 4 ); 
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // ClassBidirectional

//=======================================
// time coroutine
//=======================================

uCoroutine CoroutineDummy {
    void main() {
    } // CoroutineDummy::main
  public:
    int bidirectional( int a, int, int, int ) {
      return a;
    } // CoroutineDummy::bidirectional
}; // CoroutineDummy

void BlockCoroutineCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      CoroutineDummy dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // BlockCoroutineCreateDelete

void DynamicCoroutineCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      CoroutineDummy *dummy = new CoroutineDummy;
      delete dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // DynamicCoroutineCreateDelete

void CoroutineBidirectional( int N ) {
    int StartTime, EndTime;
    CoroutineDummy dummy;
    int i, rv;

    StartTime = Time();
    for ( i = 0; i < N; i += 1 ) {
      rv = dummy.bidirectional( 1, 2, 3, 4 ); 
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // CoroutineBidirectional

uCoroutine CoroutineResume {
    int N;

    void main() {
      for ( int i = 1; i <= N; i += 1 ) {
          uSuspend;
      } // for
    } // CoroutineResume::main
  public:
    CoroutineResume( int N ) {
      CoroutineResume::N = N;
    } // CoroutineResume::CoroutineResume

    void resumer() {
      int StartTime, EndTime;

      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uResume;
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    } // CoroutineResume::resumer
}; // CoroutineResume

//=======================================
// time monitor
//=======================================

uMutex class MonitorDummy {
  public:
    int bidirectional( int a, int, int, int ) {
      return a;
    } // MonitorDummy::bidirectional
}; // MonitorDummy

void BlockMonitorCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      MonitorDummy dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // BlockMonitorCreateDelete

void DynamicMonitorCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      MonitorDummy *dummy = new MonitorDummy;
      delete dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // DynamicMonitorCreateDelete

void MonitorBidirectional( int N ) {
    int StartTime, EndTime;
    MonitorDummy dummy;
    int i, rv;

    StartTime = Time();
    for ( i = 0; i < N; i += 1 ) {
      rv = dummy.bidirectional( 1, 2, 3, 4 ); 
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // MonitorBidirectional

uMonitor Monitor {
    uCondition condA, condB;
  public:
    volatile int here;

    Monitor() {
      here = 0;
    }; // Monitor::Monitor

    int caller( int a ) {
      return a;
    } // Monitor::caller

    void acceptor( int N ) {
      int StartTime, EndTime;

      here = 1;                           // indicate that the acceptor is in place

      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uAccept( caller );
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    } // Monitor::acceptor

    void sigwaiterA( int N ) {
      int StartTime, EndTime;

      StartTime = Time();
      for ( int i = 1;; i += 1 ) {
          uSignal condA;
        if ( i > N ) break;
          uWait condB;
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( ( EndTime - StartTime ) / N ) / 2 << uRelease;
    } // Monitor::sigwaiterA

    void sigwaiterB( int N ) {
      for ( int i = 1;; i += 1 ) {
          uSignal condB;
        if ( i > N ) break;
          uWait condA;
      } // for
    } // Monitor::sigwaiterB
}; // Monitor

uTask MonitorAcceptorPartner {
    int N;
    Monitor &m;

    void main() {
      m.acceptor( N );
    } // MonitorAcceptorPartner::main
  public:
    MonitorAcceptorPartner( int N, Monitor &m ) : m( m ) {
      MonitorAcceptorPartner::N = N;
    } // MonitorAcceptorPartner
}; // MonitorAcceptorPartner

uTask MonitorAcceptor {
    int N;

    void main() {
      Monitor m;
      MonitorAcceptorPartner partner( N, m );
      int i, rv;

      while ( m.here == 0 ) uYield();                 // wait until acceptor is in monitor

      for ( i = 1; i <= N; i += 1 ) {
          rv = m.caller( 1 );
      } // for
    } // MonitorAcceptor::main
  public:
    MonitorAcceptor( int NoOfTimes ) {
      N = NoOfTimes;
    } // MonitorAcceptor
}; // MonitorAcceptor

uTask MonitorSignallerPartner {
    int N;
    Monitor &m;

    void main() {
      m.sigwaiterB( N );
    } // MonitorSignallerPartner::main
  public:
    MonitorSignallerPartner( int N, Monitor &m ) : m( m ) {
      MonitorSignallerPartner::N = N;
    } // MonitorSignallerPartner
}; // MonitorSignallerPartner

uTask MonitorSignaller {
    int N;

    void main() {
      Monitor m;
      MonitorSignallerPartner partner( N, m );

      m.sigwaiterA( N );
    } // MonitorSignaller::main
  public:
    MonitorSignaller( int NoOfTimes ) {
      N = NoOfTimes;
    } // MonitorSignaller
}; // MonitorSignaller

//=======================================
// time coroutine-monitor
//=======================================

uMutex uCoroutine CoroutineMonitorDummy {
    void main() {}
  public:
    int bidirectional( int a, int, int, int ) {
      return a;
    } // CoroutineMonitorDummy::bidirectional
}; // CoroutineMonitorDummy

void BlockCoroutineMonitorCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      CoroutineMonitorDummy dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // BlockCoroutineMonitorCreateDelete

void DynamicCoroutineMonitorCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      CoroutineMonitorDummy *dummy = new CoroutineMonitorDummy;
      delete dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // DynamicCoroutineMonitorCreateDelete

void CoroutineMonitorBidirectional( int N ) {
    int StartTime, EndTime;
    CoroutineMonitorDummy dummy;
    int i, rv;

    StartTime = Time();
    for ( i = 0; i < N; i += 1 ) {
      rv = dummy.bidirectional( 1, 2, 3, 4 );
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // CoroutineMonitorBidirectional

uMutex uCoroutine CoroutineMonitorA {
    int N;
  public:
    volatile int here;

    CoroutineMonitorA() {
      here = 0;
    } // CoroutineMonitorA::CoroutineMonitorA

    int caller( int a ) {
      return a;
    } // CoroutineMonitorA::caller

    void acceptor( int N ) {
      CoroutineMonitorA::N = N;
      uResume;
    } // CoroutineMonitorA::acceptor
  private:
    void main() {
      int StartTime, EndTime;

      here = 1;

      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uAccept( caller );
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    }; // CoroutineMonitorA::main
}; // CoroutineMonitorA

uTask CoroutineMonitorAcceptorPartner {
    int N;
    CoroutineMonitorA &cm;

    void main() {
      cm.acceptor( N );
    } // CoroutineMonitorAcceptorPartner::main
  public:
    CoroutineMonitorAcceptorPartner( int N, CoroutineMonitorA &cm ) : cm( cm ) {
      CoroutineMonitorAcceptorPartner::N = N;
    } // CoroutineMonitorAcceptorPartner
}; // CoroutineMonitorAcceptorPartner

uTask CoroutineMonitorAcceptor {
    int N;
    void main();
  public:
    CoroutineMonitorAcceptor( int NoOfTimes ) {
      N = NoOfTimes;
    } // CoroutineMonitorAcceptor
}; // CoroutineMonitorAcceptor

void CoroutineMonitorAcceptor::main() {
    CoroutineMonitorA cm;
    CoroutineMonitorAcceptorPartner partner( N, cm );
    int i, rv;

    while ( cm.here == 0 ) uYield();
    
    for ( i = 1; i <= N; i += 1 ) {
      rv = cm.caller( 1 );
    } // for
} // CoroutineMonitorAcceptor::main

uMutex uCoroutine CoroutineMonitorResume {
    int N;

    void main() {
      for ( int i = 1; i <= N; i += 1 ) {
          uSuspend;
      } // for
    }; // CoroutineMonitorResume::main
  public:
    CoroutineMonitorResume( int N ) {
      CoroutineMonitorResume::N = N;
    } // CoroutineMonitorResume::CoroutineMonitorResume

    void resumer() {
      int StartTime, EndTime;

      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uResume;
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    }; // CoroutineMonitorResume::resumer
}; // CoroutineMonitorResume

uMutex uCoroutine CoroutineMonitorB {
    int N;
    uCondition condA, condB;

    void main() {
      int StartTime, EndTime;

      StartTime = Time();
      for ( int i = 1;; i += 1 ) {
          uSignal condA;
        if ( i > N ) break;
          uWait condB;
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( ( EndTime - StartTime ) / N ) / 2 << uRelease;
    }; // CoroutineMonitorB::main
  public:
    void sigwaiterA( int N ) {
      CoroutineMonitorB::N = N;
      uResume;
    } // CoroutineMonitorB::sigwaiterA

    void sigwaiterB( int N ) {
      for ( int i = 1;; i += 1 ) {
          uSignal condB;
        if ( i > N ) break;
          uWait condA;
      } // for
    } // CoroutineMonitorB::sigwaiterB
}; // CoroutineMonitorB

uTask CoroutineMonitorSignallerPartner {
    int N;
    CoroutineMonitorB &cm;

    void main() {
      cm.sigwaiterB( N );
    } // CoroutineMonitorSignallerPartner::main
  public:
    CoroutineMonitorSignallerPartner( int N, CoroutineMonitorB &cm ) : cm( cm ) {
      CoroutineMonitorSignallerPartner::N = N;
    } // CoroutineMonitorSignallerPartner
}; // CoroutineMonitorSignallerPartner

uTask CoroutineMonitorSignaller {
    int N;

    void main() {
      CoroutineMonitorB cm;
      CoroutineMonitorSignallerPartner partner( N, cm );

      cm.sigwaiterA( N );
    } // CoroutineMonitorSignaller::main
  public:
    CoroutineMonitorSignaller( int NoOfTimes ) {
      N = NoOfTimes;
    } // CoroutineMonitorSignaller
}; // CoroutineMonitorSignaller


//=======================================
// time task
//=======================================

uTask TaskDummy {
    void main() {
    } // TaskDummy::main
  public:
    int bidirectional( int a, int, int, int ) {
      return a;
    } // TaskDummy::bidirectional
}; // TaskDummy

void BlockTaskCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      TaskDummy dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // BlockTaskCreateDelete

void DynamicTaskCreateDelete( int N ) {
    int StartTime, EndTime;

    StartTime = Time();
    for ( int i = 0; i < N; i += 1 ) {
      TaskDummy *dummy = new TaskDummy;
      delete dummy;
    } // for
    EndTime = Time();
    uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
} // DynamicTaskCreateDelete

uTask TaskAcceptorPartner {
    int N;
  public:
    int caller( int a ) {
      return a;
    } // TaskAcceptorPartner::caller

    TaskAcceptorPartner( int N ) {
      TaskAcceptorPartner::N = N;
    } // TaskAcceptorPartner
  private:
    void main() {
      int StartTime, EndTime;
    
      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uAccept( caller );
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    } // TaskAcceptorPartner::main
}; // TaskAcceptorPartner

uTask TaskAcceptor {
    int N;

    void main() {
      TaskAcceptorPartner partner( N );
      int i, rv;

      for ( i = 1; i <= N; i += 1 ) {
          rv = partner.caller( 1 );
      } // for
    } // TaskAcceptor::main
  public:
    TaskAcceptor( int NoOfTimes ) {
      N = NoOfTimes;
    } // TaskAcceptor
}; // TaskAcceptor

uTask TaskSignallerPartner {
    int N;
    uCondition condA, condB;
  public:
    void sigwaiter( int N ) {
      for ( int i = 1;; i += 1 ) {
          uSignal condB;
        if ( i > N ) break;
          uWait condA;
      } // for
    } // TaskSignallerPartner::sigwaiter

    TaskSignallerPartner( int N ) {
      TaskSignallerPartner::N = N;
    } // TaskSignallerPartner
  private:
    void main() {
      int StartTime, EndTime;

      uAccept( sigwaiter );

      StartTime = Time();
      for ( int i = 1;; i += 1 ) {
          uSignal condA;
        if ( i > N ) break;
          uWait condB;
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( ( EndTime - StartTime ) / N ) / 2 << uRelease;
    } // TaskSignallerPartner::main
}; // TaskSignallerPartner

uTask TaskSignaller {
    int N;

    void main() {
      TaskSignallerPartner partner( N );

      partner.sigwaiter( N );
    } // TaskSignaller::main
  public:
    TaskSignaller( int NoOfTimes ) {
      N = NoOfTimes;
    } // TaskSignaller
}; // TaskSignaller

//=======================================
// time context switch
//=======================================

uTask ContextSwitch {
    int N;

    void main() {    
      int StartTime, EndTime;
      StartTime = Time();
      for ( int i = 1; i <= N; i += 1 ) {
          uYieldNoPoll();
      } // for
      EndTime = Time();
      uCerr << uAcquire << "\t " << ( EndTime - StartTime ) / N << uRelease;
    } // ContextSwitch::main
  public:
    ContextSwitch( int N ) {
      ContextSwitch::N = N;
    } // ContextSwitch
}; // ContextSwitch

//=======================================
// benchmark driver
//=======================================

void uMain::main() {
    const int NoOfTimes = 10000;

    uCerr << "\t\tcreate\tcreate\t16i/4o\t16i/4o\tresume/\tsignal/" << endl;
    uCerr << "\t\tdelete/\tdelete/\tbytes\tbytes\tsuspend\twait" << endl;
    uCerr << "\t\tblock\tdynamic\tdirect\taccept\tcycle\tcycle" << endl;

    uCerr << "class\t";
    BlockClassCreateDelete( NoOfTimes );
    DynamicClassCreateDelete( NoOfTimes );
    ClassBidirectional( NoOfTimes );
    uCerr << "\t N/A\t N/A\t N/A";
    uCerr << "\t" << endl;

    uCerr << "coroutine";
    BlockCoroutineCreateDelete( NoOfTimes );
    DynamicCoroutineCreateDelete( NoOfTimes );
    CoroutineBidirectional( NoOfTimes );
    uCerr << "\t N/A";
    {
      CoroutineResume resumer( NoOfTimes );
      resumer.resumer();
    }
    uCerr << "\t N/A";
    uCerr << "\t" << endl;

    uCerr << "monitor\t";
    BlockMonitorCreateDelete( NoOfTimes );
    DynamicMonitorCreateDelete( NoOfTimes );
    MonitorBidirectional( NoOfTimes );
    {
      MonitorAcceptor m( NoOfTimes );
    }
    uCerr << "\t N/A";
    {
      MonitorSignaller m( NoOfTimes );
    }
    uCerr << "\t" << endl;

    uCerr << "cormonitor";
    BlockCoroutineMonitorCreateDelete( NoOfTimes );
    DynamicCoroutineMonitorCreateDelete( NoOfTimes );
    CoroutineMonitorBidirectional( NoOfTimes );
    {
      CoroutineMonitorAcceptor cm( NoOfTimes );
    }
    {
      CoroutineMonitorResume resumer( NoOfTimes );
      resumer.resumer();
    }
    {
      CoroutineMonitorSignaller cm( NoOfTimes );
    }
    uCerr << "\t" << endl;

    uCerr << "task\t";
    BlockTaskCreateDelete( NoOfTimes );
    DynamicTaskCreateDelete( NoOfTimes );
    uCerr << "\t N/A";
    {
      TaskAcceptor t( NoOfTimes );
    }
    uCerr << "\t N/A";
    {
      TaskSignaller t( NoOfTimes );
    }
    uCerr << "\t" << endl;

    uCerr << "cxt sw\t";
    {
      ContextSwitch dummy( NoOfTimes );         // context switch
    }
    uCerr << "\t" << endl;

} // uMain::main

// Local Variables: //
// compile-command: "../../bin/u++ -O2 -nodebug Bench.cc" //
// End: //

Generated by  Doxygen 1.6.0   Back to index