| [550a3385] | 1 | 
 | 
|---|
 | 2 | #include <fstream>
 | 
|---|
| [a91dcc2] | 3 | #include <stdlib>
 | 
|---|
| [550a3385] | 4 | #include <threads>
 | 
|---|
 | 5 | 
 | 
|---|
 | 6 | #include <unistd.h>                                     // sysconf
 | 
|---|
 | 7 | #include <sys/times.h>                                  // times
 | 
|---|
 | 8 | #include <time.h>
 | 
|---|
 | 9 | 
 | 
|---|
 | 10 | inline unsigned long long int Time() {
 | 
|---|
 | 11 |     timespec ts;
 | 
|---|
 | 12 |     clock_gettime(
 | 
|---|
 | 13 | #if defined( __linux__ )
 | 
|---|
 | 14 |          CLOCK_THREAD_CPUTIME_ID,
 | 
|---|
 | 15 | #elif defined( __freebsd__ )
 | 
|---|
 | 16 |          CLOCK_PROF,
 | 
|---|
 | 17 | #elif defined( __solaris__ )
 | 
|---|
 | 18 |          CLOCK_HIGHRES,
 | 
|---|
 | 19 | #else
 | 
|---|
 | 20 |     #error uC++ : internal error, unsupported architecture
 | 
|---|
 | 21 | #endif
 | 
|---|
 | 22 |          &ts );
 | 
|---|
 | 23 |     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
 | 
|---|
 | 24 | } // Time
 | 
|---|
 | 25 | 
 | 
|---|
| [a91dcc2] | 26 | //=======================================
 | 
|---|
 | 27 | // time struct
 | 
|---|
 | 28 | //=======================================
 | 
|---|
 | 29 | 
 | 
|---|
 | 30 | // prevent dead-code removal
 | 
|---|
 | 31 | struct StructDummy {
 | 
|---|
 | 32 |         volatile int i;
 | 
|---|
 | 33 | };
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | void ?{}(StructDummy * this) __attribute__(( noinline )) {
 | 
|---|
 | 36 |         this->i = 2;
 | 
|---|
 | 37 | }
 | 
|---|
 | 38 | 
 | 
|---|
 | 39 | int get_i(StructDummy * this) {
 | 
|---|
 | 40 |         return this->i;
 | 
|---|
 | 41 | }
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 | forall( dtype T | { int get_i(T*); } )
 | 
|---|
 | 44 | int bidirectional( StructDummy * this ) __attribute__(( noinline )) {
 | 
|---|
 | 45 |         return get_i( this );
 | 
|---|
 | 46 | }
 | 
|---|
 | 47 | 
 | 
|---|
 | 48 | void BlockStructCreateDelete( int N ) {
 | 
|---|
 | 49 |     long long int StartTime, EndTime;
 | 
|---|
 | 50 | 
 | 
|---|
 | 51 |     StartTime = Time();
 | 
|---|
 | 52 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 53 |         StructDummy dummy;
 | 
|---|
 | 54 |     }
 | 
|---|
 | 55 |     EndTime = Time();
 | 
|---|
 | 56 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 57 | }
 | 
|---|
 | 58 | 
 | 
|---|
 | 59 | void DynamicStructCreateDelete( int N ) {
 | 
|---|
 | 60 |     long long int StartTime, EndTime;
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 |     StartTime = Time();
 | 
|---|
 | 63 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 64 |         StructDummy *dummy = new();
 | 
|---|
 | 65 |         delete(dummy);
 | 
|---|
 | 66 |     }
 | 
|---|
 | 67 |     EndTime = Time();
 | 
|---|
 | 68 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 69 | }
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | void StructBidirectional( int N ) {
 | 
|---|
 | 72 |     long long int StartTime, EndTime;
 | 
|---|
 | 73 |     StructDummy dummy;
 | 
|---|
 | 74 |     volatile int rv __attribute__(( unused ));
 | 
|---|
 | 75 | 
 | 
|---|
 | 76 |     StartTime = Time();
 | 
|---|
 | 77 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 78 |         rv = bidirectional( &dummy ); 
 | 
|---|
 | 79 |     }
 | 
|---|
 | 80 |     EndTime = Time();
 | 
|---|
 | 81 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 82 | }
 | 
|---|
 | 83 | 
 | 
|---|
| [550a3385] | 84 | //=======================================
 | 
|---|
 | 85 | // time coroutine
 | 
|---|
 | 86 | //=======================================
 | 
|---|
 | 87 | 
 | 
|---|
| [a91dcc2] | 88 | struct CoroutineDummy { coroutine c; };
 | 
|---|
| [77e6fcb] | 89 | DECL_COROUTINE(CoroutineDummy);
 | 
|---|
| [a91dcc2] | 90 | void main(CoroutineDummy * this) {}
 | 
|---|
 | 91 | 
 | 
|---|
 | 92 | void ?{}(CoroutineDummy * this) {
 | 
|---|
 | 93 |         prime(this);
 | 
|---|
 | 94 | }
 | 
|---|
 | 95 | 
 | 
|---|
 | 96 | void BlockCoroutineCreateDelete( int N ) {
 | 
|---|
 | 97 |     long long int StartTime, EndTime;
 | 
|---|
 | 98 | 
 | 
|---|
 | 99 |     StartTime = Time();
 | 
|---|
 | 100 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 101 |         CoroutineDummy dummy;
 | 
|---|
 | 102 |     }
 | 
|---|
 | 103 |     EndTime = Time();
 | 
|---|
 | 104 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 105 | }
 | 
|---|
 | 106 | 
 | 
|---|
 | 107 | void DynamicCoroutineCreateDelete( int N ) {
 | 
|---|
 | 108 |     long long int StartTime, EndTime;
 | 
|---|
 | 109 | 
 | 
|---|
 | 110 |     StartTime = Time();
 | 
|---|
 | 111 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 112 |         CoroutineDummy * dummy = new();
 | 
|---|
 | 113 |         delete(dummy);
 | 
|---|
 | 114 |     }
 | 
|---|
 | 115 |     EndTime = Time();
 | 
|---|
 | 116 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 117 | }
 | 
|---|
 | 118 | 
 | 
|---|
| [550a3385] | 119 | struct CoroutineResume {
 | 
|---|
 | 120 |     int N;
 | 
|---|
 | 121 |     coroutine c;
 | 
|---|
 | 122 | };
 | 
|---|
 | 123 | 
 | 
|---|
| [77e6fcb] | 124 | DECL_COROUTINE(CoroutineResume);
 | 
|---|
| [550a3385] | 125 | 
 | 
|---|
 | 126 | void ?{}(CoroutineResume* this, int N) {
 | 
|---|
 | 127 |       this->N = N;
 | 
|---|
 | 128 |         prime(this);
 | 
|---|
 | 129 | }
 | 
|---|
 | 130 | 
 | 
|---|
| [a91dcc2] | 131 | void main(CoroutineResume* this) {
 | 
|---|
| [550a3385] | 132 |         for ( int i = 1; i <= this->N; i += 1 ) {
 | 
|---|
 | 133 |                 suspend();
 | 
|---|
| [a91dcc2] | 134 |         }
 | 
|---|
 | 135 | }
 | 
|---|
| [550a3385] | 136 | 
 | 
|---|
 | 137 | void resumer(CoroutineResume* this) {
 | 
|---|
 | 138 |         long long int StartTime, EndTime;
 | 
|---|
 | 139 | 
 | 
|---|
 | 140 |         StartTime = Time();
 | 
|---|
 | 141 |         for ( int i = 1; i <= this->N; i += 1 ) {
 | 
|---|
 | 142 |                 resume(this);
 | 
|---|
| [a91dcc2] | 143 |         }
 | 
|---|
| [550a3385] | 144 |         EndTime = Time();
 | 
|---|
 | 145 |         sout | "\t " | ( EndTime - StartTime ) / this->N;
 | 
|---|
| [a91dcc2] | 146 | }
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 | //=======================================
 | 
|---|
 | 149 | // time task
 | 
|---|
 | 150 | //=======================================
 | 
|---|
 | 151 | 
 | 
|---|
 | 152 | struct ThreadDummy { thread t; };
 | 
|---|
| [77e6fcb] | 153 | DECL_THREAD(ThreadDummy);
 | 
|---|
| [a91dcc2] | 154 | void main(ThreadDummy * this) {}
 | 
|---|
 | 155 | 
 | 
|---|
 | 156 | void BlockTaskCreateDelete( int N ) {
 | 
|---|
 | 157 |     long long int StartTime, EndTime;
 | 
|---|
 | 158 | 
 | 
|---|
 | 159 |     StartTime = Time();
 | 
|---|
 | 160 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 161 |         scoped(ThreadDummy) dummy;
 | 
|---|
 | 162 |     }
 | 
|---|
 | 163 |     EndTime = Time();
 | 
|---|
 | 164 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 165 | }
 | 
|---|
 | 166 | 
 | 
|---|
 | 167 | void DynamicTaskCreateDelete( int N ) {
 | 
|---|
 | 168 |     long long int StartTime, EndTime;
 | 
|---|
 | 169 | 
 | 
|---|
 | 170 |     StartTime = Time();
 | 
|---|
 | 171 |     for ( int i = 0; i < N; i += 1 ) {
 | 
|---|
 | 172 |         scoped(ThreadDummy) * dummy = new();
 | 
|---|
 | 173 |         delete(dummy);
 | 
|---|
 | 174 |     }
 | 
|---|
 | 175 |     EndTime = Time();
 | 
|---|
 | 176 |     sout | "\t " | ( EndTime - StartTime ) / N;
 | 
|---|
 | 177 | }
 | 
|---|
 | 178 | 
 | 
|---|
 | 179 | struct ContextSwitch {
 | 
|---|
 | 180 |     int N;
 | 
|---|
 | 181 |     long long result;
 | 
|---|
 | 182 |     thread t;
 | 
|---|
 | 183 | };
 | 
|---|
 | 184 | 
 | 
|---|
| [77e6fcb] | 185 | DECL_THREAD(ContextSwitch);
 | 
|---|
| [a91dcc2] | 186 | 
 | 
|---|
 | 187 | void main(ContextSwitch * this) {    
 | 
|---|
 | 188 |         long long int StartTime, EndTime;
 | 
|---|
 | 189 | 
 | 
|---|
 | 190 |         StartTime = Time();
 | 
|---|
 | 191 |         for ( int i = 1; i <= this->N; i += 1 ) {
 | 
|---|
 | 192 |             yield();
 | 
|---|
 | 193 |         } // for
 | 
|---|
 | 194 |         EndTime = Time();
 | 
|---|
 | 195 |         this->result = ( EndTime - StartTime ) / this->N;
 | 
|---|
 | 196 | }
 | 
|---|
 | 197 | 
 | 
|---|
 | 198 | void ?{}(ContextSwitch * this, int N) {
 | 
|---|
 | 199 |         this->N = N;
 | 
|---|
 | 200 | }
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 | void ^?{}(ContextSwitch * this) {
 | 
|---|
 | 203 |         sout | "\t " | this->result;
 | 
|---|
 | 204 | }
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 | //=======================================
 | 
|---|
 | 207 | // benchmark driver
 | 
|---|
 | 208 | //=======================================
 | 
|---|
| [550a3385] | 209 | 
 | 
|---|
 | 210 | 
 | 
|---|
 | 211 | int main() {
 | 
|---|
 | 212 |         const int NoOfTimes =
 | 
|---|
 | 213 | #if defined( __U_DEBUG__ )                              // takes longer so run fewer iterations
 | 
|---|
 | 214 |         100000;
 | 
|---|
 | 215 | #else
 | 
|---|
 | 216 |         1000000;
 | 
|---|
 | 217 | #endif // __U_DEBUG__
 | 
|---|
 | 218 | 
 | 
|---|
| [a91dcc2] | 219 |         sout | "\t\tcreate\tcreate\tcall/" | endl;
 | 
|---|
| [550a3385] | 220 |         sout | "(nsecs)";
 | 
|---|
| [a91dcc2] | 221 |         sout | "\t\tdelete/\tdelete/\tctx" | endl;
 | 
|---|
 | 222 |         sout | "\t\tblock\tdynamic\tcycle" | endl;
 | 
|---|
| [550a3385] | 223 | 
 | 
|---|
| [a91dcc2] | 224 |         sout | "object\t";
 | 
|---|
 | 225 |         BlockStructCreateDelete( NoOfTimes );
 | 
|---|
 | 226 |         DynamicStructCreateDelete( NoOfTimes );
 | 
|---|
 | 227 |         StructBidirectional( NoOfTimes );
 | 
|---|
 | 228 |         sout | endl;
 | 
|---|
| [550a3385] | 229 | 
 | 
|---|
 | 230 |         sout | "coroutine";
 | 
|---|
| [a91dcc2] | 231 |         BlockCoroutineCreateDelete( NoOfTimes );
 | 
|---|
 | 232 |         DynamicCoroutineCreateDelete( NoOfTimes );
 | 
|---|
| [550a3385] | 233 |         {
 | 
|---|
 | 234 |                 CoroutineResume resumer = { NoOfTimes };
 | 
|---|
 | 235 |                 resumer(&resumer);
 | 
|---|
 | 236 |         }
 | 
|---|
| [a91dcc2] | 237 |         sout | endl;
 | 
|---|
| [550a3385] | 238 | 
 | 
|---|
| [a91dcc2] | 239 |         sout | "task\t";
 | 
|---|
 | 240 |         BlockTaskCreateDelete( NoOfTimes );
 | 
|---|
 | 241 |         DynamicTaskCreateDelete( NoOfTimes );
 | 
|---|
 | 242 |         {
 | 
|---|
 | 243 |                 scoped(ContextSwitch) dummy = { (int)NoOfTimes };               // context switch
 | 
|---|
 | 244 |         }
 | 
|---|
| [550a3385] | 245 |         sout | "\t" | endl;
 | 
|---|
 | 246 | }
 | 
|---|