#include #include #include #include // sysconf #include // times #include inline unsigned long long int Time() { timespec ts; clock_gettime( #if defined( __linux__ ) CLOCK_THREAD_CPUTIME_ID, #elif defined( __freebsd__ ) CLOCK_PROF, #elif defined( __solaris__ ) CLOCK_HIGHRES, #else #error uC++ : internal error, unsupported architecture #endif &ts ); return 1000000000LL * ts.tv_sec + ts.tv_nsec; } // Time //======================================= // time struct //======================================= // prevent dead-code removal struct StructDummy { volatile int i; }; void ?{}(StructDummy * this) __attribute__(( noinline )) { this->i = 2; } int get_i(StructDummy * this) { return this->i; } forall( dtype T | { int get_i(T*); } ) int bidirectional( StructDummy * this ) __attribute__(( noinline )) { return get_i( this ); } void BlockStructCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { StructDummy dummy; } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } void DynamicStructCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { StructDummy *dummy = new(); delete(dummy); } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } void StructBidirectional( int N ) { long long int StartTime, EndTime; StructDummy dummy; volatile int rv __attribute__(( unused )); StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { rv = bidirectional( &dummy ); } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } //======================================= // time coroutine //======================================= struct CoroutineDummy { coroutine c; }; DECL_COROUTINE(CoroutineDummy); void main(CoroutineDummy * this) {} void ?{}(CoroutineDummy * this) { prime(this); } void BlockCoroutineCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { CoroutineDummy dummy; } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } void DynamicCoroutineCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { CoroutineDummy * dummy = new(); delete(dummy); } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } struct CoroutineResume { int N; coroutine c; }; DECL_COROUTINE(CoroutineResume); void ?{}(CoroutineResume* this, int N) { this->N = N; prime(this); } void main(CoroutineResume* this) { for ( int i = 1; i <= this->N; i += 1 ) { suspend(); } } void resumer(CoroutineResume* this) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 1; i <= this->N; i += 1 ) { resume(this); } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / this->N; } //======================================= // time task //======================================= struct ThreadDummy { thread t; }; DECL_THREAD(ThreadDummy); void main(ThreadDummy * this) {} void BlockTaskCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { scoped(ThreadDummy) dummy; } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } void DynamicTaskCreateDelete( int N ) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 0; i < N; i += 1 ) { scoped(ThreadDummy) * dummy = new(); delete(dummy); } EndTime = Time(); sout | "\t " | ( EndTime - StartTime ) / N; } struct ContextSwitch { int N; long long result; thread t; }; DECL_THREAD(ContextSwitch); void main(ContextSwitch * this) { long long int StartTime, EndTime; StartTime = Time(); for ( int i = 1; i <= this->N; i += 1 ) { yield(); } // for EndTime = Time(); this->result = ( EndTime - StartTime ) / this->N; } void ?{}(ContextSwitch * this, int N) { this->N = N; } void ^?{}(ContextSwitch * this) { sout | "\t " | this->result; } //======================================= // benchmark driver //======================================= int main() { const int NoOfTimes = #if defined( __U_DEBUG__ ) // takes longer so run fewer iterations 100000; #else 1000000; #endif // __U_DEBUG__ sout | "\t\tcreate\tcreate\tcall/" | endl; sout | "(nsecs)"; sout | "\t\tdelete/\tdelete/\tctx" | endl; sout | "\t\tblock\tdynamic\tcycle" | endl; sout | "object\t"; BlockStructCreateDelete( NoOfTimes ); DynamicStructCreateDelete( NoOfTimes ); StructBidirectional( NoOfTimes ); sout | endl; sout | "coroutine"; BlockCoroutineCreateDelete( NoOfTimes ); DynamicCoroutineCreateDelete( NoOfTimes ); { CoroutineResume resumer = { NoOfTimes }; resumer(&resumer); } sout | endl; sout | "task\t"; BlockTaskCreateDelete( NoOfTimes ); DynamicTaskCreateDelete( NoOfTimes ); { scoped(ContextSwitch) dummy = { (int)NoOfTimes }; // context switch } sout | "\t" | endl; }