Changes in / [665edf40:c8a0210]
- Files:
-
- 19 edited
-
benchmark/benchcltr.hfa (modified) (3 diffs)
-
benchmark/io/http/protocol.cfa (modified) (1 diff)
-
benchmark/io/readv-posix.c (modified) (2 diffs)
-
benchmark/io/readv.cfa (modified) (2 diffs)
-
benchmark/readyQ/cycle.cc (modified) (2 diffs)
-
benchmark/readyQ/cycle.cfa (modified) (2 diffs)
-
benchmark/readyQ/cycle.cpp (modified) (2 diffs)
-
benchmark/readyQ/locality.cc (modified) (2 diffs)
-
benchmark/readyQ/locality.cfa (modified) (2 diffs)
-
benchmark/readyQ/locality.cpp (modified) (2 diffs)
-
benchmark/readyQ/rq_bench.hfa (modified) (1 diff)
-
benchmark/readyQ/rq_bench.hpp (modified) (2 diffs)
-
benchmark/readyQ/yield.cfa (modified) (2 diffs)
-
example/io/batch-readv.c (modified) (2 diffs)
-
libcfa/src/clock.hfa (modified) (8 diffs)
-
libcfa/src/concurrency/ready_queue.cfa (modified) (15 diffs)
-
libcfa/src/concurrency/stats.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/stats.hfa (modified) (2 diffs)
-
tests/time.cfa (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
benchmark/benchcltr.hfa
r665edf40 rc8a0210 114 114 for() { 115 115 sleep(100`ms); 116 end = time HiRes();116 end = timeNsec(); 117 117 Duration delta = end - start; 118 118 /*if(is_tty)*/ { … … 126 126 } 127 127 #else 128 uint64_t time HiRes() {128 uint64_t timeNsec() { 129 129 timespec curr; 130 130 clock_gettime( CLOCK_REALTIME, &curr ); … … 140 140 for(;;) { 141 141 usleep(100000); 142 end = time HiRes();142 end = timeNsec(); 143 143 uint64_t delta = end - start; 144 144 /*if(is_tty)*/ { -
benchmark/io/http/protocol.cfa
r665edf40 rc8a0210 249 249 250 250 char buff[100]; 251 Time now = time HiRes();251 Time now = timeNsec(); 252 252 strftime( buff, 100, "%a, %d %b %Y %H:%M:%S %Z", now ); 253 253 sout | "Updated date to '" | buff | "'"; -
benchmark/io/readv-posix.c
r665edf40 rc8a0210 111 111 printf("Starting\n"); 112 112 bool is_tty = isatty(STDOUT_FILENO); 113 start = time HiRes();113 start = timeNsec(); 114 114 run = true; 115 115 … … 118 118 119 119 run = false; 120 end = time HiRes();120 end = timeNsec(); 121 121 printf("\nDone\n"); 122 122 -
benchmark/io/readv.cfa
r665edf40 rc8a0210 147 147 printf("Starting\n"); 148 148 bool is_tty = isatty(STDOUT_FILENO); 149 start = time HiRes();149 start = timeNsec(); 150 150 run = true; 151 151 … … 156 156 157 157 run = false; 158 end = time HiRes();158 end = timeNsec(); 159 159 printf("\nDone\n"); 160 160 } -
benchmark/readyQ/cycle.cc
r665edf40 rc8a0210 89 89 90 90 bool is_tty = isatty(STDOUT_FILENO); 91 start = time HiRes();91 start = timeNsec(); 92 92 93 93 for(int i = 0; i < nthreads; i++) { … … 97 97 98 98 stop = true; 99 end = time HiRes();99 end = timeNsec(); 100 100 printf("\nDone\n"); 101 101 -
benchmark/readyQ/cycle.cfa
r665edf40 rc8a0210 65 65 66 66 bool is_tty = isatty(STDOUT_FILENO); 67 start = time HiRes();67 start = timeNsec(); 68 68 69 69 for(i; nthreads) { … … 73 73 74 74 stop = true; 75 end = time HiRes();75 end = timeNsec(); 76 76 printf("\nDone\n"); 77 77 -
benchmark/readyQ/cycle.cpp
r665edf40 rc8a0210 93 93 94 94 bool is_tty = isatty(STDOUT_FILENO); 95 start = time HiRes();95 start = timeNsec(); 96 96 97 97 for(int i = 0; i < nthreads; i++) { … … 101 101 102 102 stop = true; 103 end = time HiRes();103 end = timeNsec(); 104 104 printf("\nDone\n"); 105 105 -
benchmark/readyQ/locality.cc
r665edf40 rc8a0210 281 281 282 282 bool is_tty = isatty(STDOUT_FILENO); 283 start = time HiRes();283 start = timeNsec(); 284 284 285 285 for(size_t i = 0; i < nthreads; i++) { … … 289 289 290 290 stop = true; 291 end = time HiRes();291 end = timeNsec(); 292 292 printf("\nDone\n"); 293 293 -
benchmark/readyQ/locality.cfa
r665edf40 rc8a0210 232 232 233 233 bool is_tty = isatty(STDOUT_FILENO); 234 start = time HiRes();234 start = timeNsec(); 235 235 236 236 for(i; nthreads) { … … 240 240 241 241 stop = true; 242 end = time HiRes();242 end = timeNsec(); 243 243 printf("\nDone\n"); 244 244 -
benchmark/readyQ/locality.cpp
r665edf40 rc8a0210 287 287 288 288 bool is_tty = isatty(STDOUT_FILENO); 289 start = time HiRes();289 start = timeNsec(); 290 290 291 291 for(size_t i = 0; i < nthreads; i++) { … … 295 295 296 296 stop = true; 297 end = time HiRes();297 end = timeNsec(); 298 298 printf("\nDone\n"); 299 299 -
benchmark/readyQ/rq_bench.hfa
r665edf40 rc8a0210 73 73 for() { 74 74 sleep(100`ms); 75 Time end = time HiRes();75 Time end = timeNsec(); 76 76 Duration delta = end - start; 77 77 if(is_tty) { -
benchmark/readyQ/rq_bench.hpp
r665edf40 rc8a0210 46 46 } 47 47 48 uint64_t time HiRes() {48 uint64_t timeNsec() { 49 49 timespec curr; 50 50 clock_gettime( CLOCK_REALTIME, &curr ); … … 60 60 for(;;) { 61 61 Sleeper::usleep(100000); 62 uint64_t end = time HiRes();62 uint64_t end = timeNsec(); 63 63 uint64_t delta = end - start; 64 64 if(is_tty) { -
benchmark/readyQ/yield.cfa
r665edf40 rc8a0210 66 66 67 67 bool is_tty = isatty(STDOUT_FILENO); 68 start = time HiRes();68 start = timeNsec(); 69 69 run = true; 70 70 … … 75 75 76 76 run = false; 77 end = time HiRes();77 end = timeNsec(); 78 78 printf("\nDone\n"); 79 79 } -
example/io/batch-readv.c
r665edf40 rc8a0210 66 66 } 67 67 68 uint64_t timeHiRes() {68 uint64_t getTimeNsec() { 69 69 timespec curr; 70 70 clock_gettime( CLOCK_REALTIME, &curr ); … … 163 163 164 164 printf("Running for %f second, reading %d bytes in batches of %d\n", duration, buflen, batch); 165 uint64_t start = timeHiRes();166 uint64_t end = timeHiRes();167 uint64_t prev = timeHiRes();165 uint64_t start = getTimeNsec(); 166 uint64_t end = getTimeNsec(); 167 uint64_t prev = getTimeNsec(); 168 168 for(;;) { 169 169 submit_and_drain(&iov, batch); 170 end = timeHiRes();170 end = getTimeNsec(); 171 171 uint64_t delta = end - start; 172 172 if( to_fseconds(end - prev) > 0.1 ) { -
libcfa/src/clock.hfa
r665edf40 rc8a0210 10 10 // Created On : Thu Apr 12 14:36:06 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 18 08:12:16202113 // Update Count : 2 812 // Last Modified On : Wed Apr 14 17:48:25 2021 13 // Update Count : 20 14 14 // 15 15 … … 27 27 //######################### Clock ######################### 28 28 29 struct Clock { // virtual clock 30 // private 31 Duration offset; // offset from computer real-time 29 struct Clock { // private 30 Duration offset; // for virtual clock: contains offset from real-time 32 31 }; 33 32 34 33 static inline { 35 void reset( Clock & clk, Duration adj ) with( clk ) { // change offset34 void reset( Clock & clk, Duration adj ) with( clk ) { 36 35 offset = adj + __timezone`s; // timezone (global) is (UTC - local time) in seconds 37 36 } // reset 38 37 39 void ?{}( Clock & clk ) { reset( clk, (Duration){ 0 } ); } // create no offset40 void ?{}( Clock & clk, Duration adj ) { reset( clk, adj ); } // create with offset38 void ?{}( Clock & clk ) { reset( clk, (Duration){ 0 } ); } 39 void ?{}( Clock & clk, Duration adj ) { reset( clk, adj ); } 41 40 42 41 // System-wide clock that measures real, i.e., wall-clock) time. This clock is affected by discontinuous jumps in 43 42 // the system time. For example, manual changes of the clock, and incremental adjustments performed by adjtime(3) 44 43 // and NTP (daylight saving (Fall back). 45 Duration resolution Hi() { // clock resolution in nanoseconds (fine)44 Duration resolutionNsec() { 46 45 struct timespec res; 47 46 clock_getres( CLOCK_REALTIME, &res ); 48 47 return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns; 49 } // resolution Hi48 } // resolutionNsec 50 49 51 Duration resolution() { // clock resolution without nanoseconds (coarse)50 Duration resolution() { 52 51 struct timespec res; 53 52 clock_getres( CLOCK_REALTIME_COARSE, &res ); … … 55 54 } // resolution 56 55 57 Time time HiRes() { // real timewith nanoseconds56 Time timeNsec() { // with nanoseconds 58 57 timespec curr; 59 58 clock_gettime( CLOCK_REALTIME, &curr ); 60 59 return (Time){ curr }; 61 } // time HiRes60 } // timeNsec 62 61 63 Time time() { // real timewithout nanoseconds62 Time time() { // without nanoseconds 64 63 timespec curr; 65 64 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); … … 68 67 } // time 69 68 70 Time time( Clock & clk ) with( clk ) { // real time for given clock69 Time time( Clock & clk ) with( clk ) { 71 70 return time() + offset; 72 71 } // time … … 76 75 } // ?() 77 76 78 timeval time( Clock & clk ) { // convert to C time format77 timeval time( Clock & clk ) { 79 78 return (timeval){ clk() }; 80 79 } // time … … 89 88 // discontinuous jumps when the OS is not running the kernal thread. A duration is returned because the value is 90 89 // relative and cannot be converted to real-time (wall-clock) time. 91 Duration processor() { // non-monotonic duration of kernel thread90 Duration processor() { 92 91 timespec ts; 93 92 clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ); … … 98 97 // watch is affected by discontinuous jumps when the OS is not running the kernel threads. A duration is returned 99 98 // because the value is relative and cannot be converted to real-time (wall-clock) time. 100 Duration program() { // non-monotonic duration of program CPU99 Duration program() { 101 100 timespec ts; 102 101 clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &ts ); … … 104 103 } // program 105 104 106 // Monotonic duration from machine boot and including system suspension. This watch is unaffected by discontinuous107 // jumps resulting from manual changes of the clock, and incremental adjustments performed by adjtime(3) and NTP108 // (Fall back). A duration is returned because the value is relative and cannot be converted to real-time109 // (wall-clock) time.110 Duration boot() { // monotonic duration since computer boot105 // Monotonic stopwatch starting at machine boot and includes system suspension. This watch is unaffected by 106 // discontinuous jumps resulting from manual changes of the clock, and incremental adjustments performed by 107 // adjtime(3) and NTP (Fall back). A duration is returned because the value is relative and cannot be converted to 108 // real-time (wall-clock) time. 109 Duration boot() { 111 110 timespec ts; 112 111 clock_gettime( CLOCK_BOOTTIME, &ts ); -
libcfa/src/concurrency/ready_queue.cfa
r665edf40 rc8a0210 35 35 static const size_t cache_line_size = 64; 36 36 37 #if !defined(__CFA_NO_STATISTICS__)38 #define __STATS(...) __VA_ARGS__39 #else40 #define __STATS(...)41 #endif42 43 37 // No overriden function, no environment variable, no define 44 38 // fall back to a magic number … … 58 52 #endif 59 53 60 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)); 61 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)); 54 static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred); 55 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w); 56 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j); 62 57 static inline struct $thread * search(struct cluster * cltr); 63 static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred);64 58 65 59 … … 275 269 276 270 #if !defined(__CFA_NO_STATISTICS__) 277 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.attempt, 1, __ATOMIC_RELAXED); 278 else if(local) __tls_stats()->ready.push.local.attempt++; 279 else __tls_stats()->ready.push.share.attempt++; 271 if(external) { 272 if(local) __atomic_fetch_add(&cltr->stats->ready.pick.ext.local, 1, __ATOMIC_RELAXED); 273 __atomic_fetch_add(&cltr->stats->ready.pick.ext.attempt, 1, __ATOMIC_RELAXED); 274 } 275 else { 276 if(local) __tls_stats()->ready.pick.push.local++; 277 __tls_stats()->ready.pick.push.attempt++; 278 } 280 279 #endif 281 280 … … 303 302 // Update statistics 304 303 #if !defined(__CFA_NO_STATISTICS__) 305 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.success, 1, __ATOMIC_RELAXED); 306 else if(local) __tls_stats()->ready.push.local.success++; 307 else __tls_stats()->ready.push.share.success++; 304 if(external) { 305 if(local) __atomic_fetch_add(&cltr->stats->ready.pick.ext.lsuccess, 1, __ATOMIC_RELAXED); 306 __atomic_fetch_add(&cltr->stats->ready.pick.ext.success, 1, __ATOMIC_RELAXED); 307 } 308 else { 309 if(local) __tls_stats()->ready.pick.push.lsuccess++; 310 __tls_stats()->ready.pick.push.success++; 311 } 308 312 #endif 309 313 } … … 330 334 [j, localj] = idx_from_r(rj, preferred); 331 335 336 #if !defined(__CFA_NO_STATISTICS__) 337 if(locali && localj) { 338 __tls_stats()->ready.pick.pop.local++; 339 } 340 #endif 341 332 342 i %= count; 333 343 j %= count; 334 344 335 345 // try popping from the 2 picked lists 336 struct $thread * thrd = try_pop(cltr, i, j __STATS(, *(locali || localj ? &__tls_stats()->ready.pop.local : &__tls_stats()->ready.pop.help)));346 struct $thread * thrd = try_pop(cltr, i, j); 337 347 if(thrd) { 348 #if !defined(__CFA_NO_STATISTICS__) 349 if( locali || localj ) __tls_stats()->ready.pick.pop.lsuccess++; 350 #endif 338 351 return thrd; 339 352 } … … 361 374 unsigned i; 362 375 do { 363 #if !defined(__CFA_NO_STATISTICS__)364 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.attempt, 1, __ATOMIC_RELAXED);365 else __tls_stats()->ready.push.local.attempt++;366 #endif367 368 376 if(unlikely(external)) { 369 377 i = __tls_rand() % lanes.count; … … 390 398 // Unlock and return 391 399 __atomic_unlock( &lanes.data[i].lock ); 392 #endif393 394 #if !defined(__CFA_NO_STATISTICS__)395 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.success, 1, __ATOMIC_RELAXED);396 else __tls_stats()->ready.push.local.success++;397 400 #endif 398 401 … … 419 422 } 420 423 else if(lanes.tscs[proc->rdq.target].tv < proc->rdq.cutoff) { 421 $thread * t = try_pop(cltr, proc->rdq.target __STATS(, __tls_stats()->ready.pop.help));424 $thread * t = try_pop(cltr, proc->rdq.target); 422 425 proc->rdq.target = -1u; 423 426 if(t) return t; … … 426 429 for(READYQ_SHARD_FACTOR) { 427 430 unsigned i = proc->rdq.id + (--proc->rdq.itr % READYQ_SHARD_FACTOR); 428 if($thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;431 if($thread * t = try_pop(cltr, i)) return t; 429 432 } 430 433 return 0p; … … 434 437 for(25) { 435 438 unsigned i = __tls_rand() % lanes.count; 436 $thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal));439 $thread * t = try_pop(cltr, i); 437 440 if(t) return t; 438 441 } … … 450 453 //----------------------------------------------------------------------- 451 454 // try to pop from a lane given by index w 452 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) { 453 __STATS( stats.attempt++; ) 454 455 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w) with (cltr->ready_queue) { 455 456 // Get relevant elements locally 456 457 __intrusive_lane_t & lane = lanes.data[w]; 457 458 458 459 // If list looks empty retry 459 if( is_empty(lane) ) { 460 __STATS( stats.espec++; ) 461 return 0p; 462 } 460 if( is_empty(lane) ) return 0p; 463 461 464 462 // If we can't get the lock retry 465 if( !__atomic_try_acquire(&lane.lock) ) { 466 __STATS( stats.elock++; ) 467 return 0p; 468 } 463 if( !__atomic_try_acquire(&lane.lock) ) return 0p; 469 464 470 465 // If list is empty, unlock and retry 471 466 if( is_empty(lane) ) { 472 467 __atomic_unlock(&lane.lock); 473 __STATS( stats.eempty++; )474 468 return 0p; 475 469 } … … 486 480 487 481 // Update statistics 488 __STATS( stats.success++; ) 482 #if !defined(__CFA_NO_STATISTICS__) 483 __tls_stats()->ready.pick.pop.success++; 484 #endif 489 485 490 486 #if defined(USE_WORK_STEALING) … … 505 501 for(i; count) { 506 502 unsigned idx = (offset + i) % count; 507 struct $thread * thrd = try_pop(cltr, idx __STATS(, __tls_stats()->ready.pop.search));503 struct $thread * thrd = try_pop(cltr, idx); 508 504 if(thrd) { 509 505 return thrd; … … 543 539 //----------------------------------------------------------------------- 544 540 // Given 2 indexes, pick the list with the oldest push an try to pop from it 545 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) { 541 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j) with (cltr->ready_queue) { 542 #if !defined(__CFA_NO_STATISTICS__) 543 __tls_stats()->ready.pick.pop.attempt++; 544 #endif 545 546 546 // Pick the bet list 547 547 int w = i; … … 550 550 } 551 551 552 return try_pop(cltr, w __STATS(, stats));552 return try_pop(cltr, w); 553 553 } 554 554 -
libcfa/src/concurrency/stats.cfa
r665edf40 rc8a0210 10 10 #if !defined(__CFA_NO_STATISTICS__) 11 11 void __init_stats( struct __stats_t * stats ) { 12 stats->ready.push.local.attempt = 0; 13 stats->ready.push.local.success = 0; 14 stats->ready.push.share.attempt = 0; 15 stats->ready.push.share.success = 0; 16 stats->ready.push.extrn.attempt = 0; 17 stats->ready.push.extrn.success = 0; 18 stats->ready.pop.local .attempt = 0; 19 stats->ready.pop.local .success = 0; 20 stats->ready.pop.local .elock = 0; 21 stats->ready.pop.local .eempty = 0; 22 stats->ready.pop.local .espec = 0; 23 stats->ready.pop.help .attempt = 0; 24 stats->ready.pop.help .success = 0; 25 stats->ready.pop.help .elock = 0; 26 stats->ready.pop.help .eempty = 0; 27 stats->ready.pop.help .espec = 0; 28 stats->ready.pop.steal .attempt = 0; 29 stats->ready.pop.steal .success = 0; 30 stats->ready.pop.steal .elock = 0; 31 stats->ready.pop.steal .eempty = 0; 32 stats->ready.pop.steal .espec = 0; 33 stats->ready.pop.search.attempt = 0; 34 stats->ready.pop.search.success = 0; 35 stats->ready.pop.search.elock = 0; 36 stats->ready.pop.search.eempty = 0; 37 stats->ready.pop.search.espec = 0; 12 stats->ready.pick.push.attempt = 0; 13 stats->ready.pick.push.success = 0; 14 stats->ready.pick.push.local = 0; 15 stats->ready.pick.push.lsuccess = 0; 16 stats->ready.pick.ext.attempt = 0; 17 stats->ready.pick.ext.success = 0; 18 stats->ready.pick.ext.local = 0; 19 stats->ready.pick.ext.lsuccess = 0; 20 stats->ready.pick.pop .probe = 0; 21 stats->ready.pick.pop .attempt = 0; 22 stats->ready.pick.pop .success = 0; 23 stats->ready.pick.pop .local = 0; 24 stats->ready.pick.pop .lsuccess = 0; 38 25 stats->ready.threads.migration = 0; 39 26 stats->ready.threads.threads = 0; … … 67 54 68 55 void __tally_stats( struct __stats_t * cltr, struct __stats_t * proc ) { 69 __atomic_fetch_add( &cltr->ready.push.local.attempt, proc->ready.push.local.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.local.attempt = 0; 70 __atomic_fetch_add( &cltr->ready.push.local.success, proc->ready.push.local.success, __ATOMIC_SEQ_CST ); proc->ready.push.local.success = 0; 71 __atomic_fetch_add( &cltr->ready.push.share.attempt, proc->ready.push.share.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.share.attempt = 0; 72 __atomic_fetch_add( &cltr->ready.push.share.success, proc->ready.push.share.success, __ATOMIC_SEQ_CST ); proc->ready.push.share.success = 0; 73 __atomic_fetch_add( &cltr->ready.push.extrn.attempt, proc->ready.push.extrn.attempt, __ATOMIC_SEQ_CST ); proc->ready.push.extrn.attempt = 0; 74 __atomic_fetch_add( &cltr->ready.push.extrn.success, proc->ready.push.extrn.success, __ATOMIC_SEQ_CST ); proc->ready.push.extrn.success = 0; 75 __atomic_fetch_add( &cltr->ready.pop.local .attempt, proc->ready.pop.local .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.local .attempt = 0; 76 __atomic_fetch_add( &cltr->ready.pop.local .success, proc->ready.pop.local .success, __ATOMIC_SEQ_CST ); proc->ready.pop.local .success = 0; 77 __atomic_fetch_add( &cltr->ready.pop.local .elock , proc->ready.pop.local .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.local .elock = 0; 78 __atomic_fetch_add( &cltr->ready.pop.local .eempty , proc->ready.pop.local .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.local .eempty = 0; 79 __atomic_fetch_add( &cltr->ready.pop.local .espec , proc->ready.pop.local .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.local .espec = 0; 80 __atomic_fetch_add( &cltr->ready.pop.help .attempt, proc->ready.pop.help .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.help .attempt = 0; 81 __atomic_fetch_add( &cltr->ready.pop.help .success, proc->ready.pop.help .success, __ATOMIC_SEQ_CST ); proc->ready.pop.help .success = 0; 82 __atomic_fetch_add( &cltr->ready.pop.help .elock , proc->ready.pop.help .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.help .elock = 0; 83 __atomic_fetch_add( &cltr->ready.pop.help .eempty , proc->ready.pop.help .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.help .eempty = 0; 84 __atomic_fetch_add( &cltr->ready.pop.help .espec , proc->ready.pop.help .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.help .espec = 0; 85 __atomic_fetch_add( &cltr->ready.pop.steal .attempt, proc->ready.pop.steal .attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.steal .attempt = 0; 86 __atomic_fetch_add( &cltr->ready.pop.steal .success, proc->ready.pop.steal .success, __ATOMIC_SEQ_CST ); proc->ready.pop.steal .success = 0; 87 __atomic_fetch_add( &cltr->ready.pop.steal .elock , proc->ready.pop.steal .elock , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .elock = 0; 88 __atomic_fetch_add( &cltr->ready.pop.steal .eempty , proc->ready.pop.steal .eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .eempty = 0; 89 __atomic_fetch_add( &cltr->ready.pop.steal .espec , proc->ready.pop.steal .espec , __ATOMIC_SEQ_CST ); proc->ready.pop.steal .espec = 0; 90 __atomic_fetch_add( &cltr->ready.pop.search.attempt, proc->ready.pop.search.attempt, __ATOMIC_SEQ_CST ); proc->ready.pop.search.attempt = 0; 91 __atomic_fetch_add( &cltr->ready.pop.search.success, proc->ready.pop.search.success, __ATOMIC_SEQ_CST ); proc->ready.pop.search.success = 0; 92 __atomic_fetch_add( &cltr->ready.pop.search.elock , proc->ready.pop.search.elock , __ATOMIC_SEQ_CST ); proc->ready.pop.search.elock = 0; 93 __atomic_fetch_add( &cltr->ready.pop.search.eempty , proc->ready.pop.search.eempty , __ATOMIC_SEQ_CST ); proc->ready.pop.search.eempty = 0; 94 __atomic_fetch_add( &cltr->ready.pop.search.espec , proc->ready.pop.search.espec , __ATOMIC_SEQ_CST ); proc->ready.pop.search.espec = 0; 56 __atomic_fetch_add( &cltr->ready.pick.push.attempt , proc->ready.pick.push.attempt , __ATOMIC_SEQ_CST ); proc->ready.pick.push.attempt = 0; 57 __atomic_fetch_add( &cltr->ready.pick.push.success , proc->ready.pick.push.success , __ATOMIC_SEQ_CST ); proc->ready.pick.push.success = 0; 58 __atomic_fetch_add( &cltr->ready.pick.push.local , proc->ready.pick.push.local , __ATOMIC_SEQ_CST ); proc->ready.pick.push.local = 0; 59 __atomic_fetch_add( &cltr->ready.pick.push.lsuccess, proc->ready.pick.push.lsuccess, __ATOMIC_SEQ_CST ); proc->ready.pick.push.lsuccess = 0; 60 __atomic_fetch_add( &cltr->ready.pick.ext.attempt , proc->ready.pick.ext.attempt , __ATOMIC_SEQ_CST ); proc->ready.pick.ext.attempt = 0; 61 __atomic_fetch_add( &cltr->ready.pick.ext.success , proc->ready.pick.ext.success , __ATOMIC_SEQ_CST ); proc->ready.pick.ext.success = 0; 62 __atomic_fetch_add( &cltr->ready.pick.ext.local , proc->ready.pick.ext.local , __ATOMIC_SEQ_CST ); proc->ready.pick.ext.local = 0; 63 __atomic_fetch_add( &cltr->ready.pick.ext.lsuccess , proc->ready.pick.ext.lsuccess , __ATOMIC_SEQ_CST ); proc->ready.pick.ext.lsuccess = 0; 64 __atomic_fetch_add( &cltr->ready.pick.pop .probe , proc->ready.pick.pop .probe , __ATOMIC_SEQ_CST ); proc->ready.pick.pop .probe = 0; 65 __atomic_fetch_add( &cltr->ready.pick.pop .attempt , proc->ready.pick.pop .attempt , __ATOMIC_SEQ_CST ); proc->ready.pick.pop .attempt = 0; 66 __atomic_fetch_add( &cltr->ready.pick.pop .success , proc->ready.pick.pop .success , __ATOMIC_SEQ_CST ); proc->ready.pick.pop .success = 0; 67 __atomic_fetch_add( &cltr->ready.pick.pop .local , proc->ready.pick.pop .local , __ATOMIC_SEQ_CST ); proc->ready.pick.pop .local = 0; 68 __atomic_fetch_add( &cltr->ready.pick.pop .lsuccess, proc->ready.pick.pop .lsuccess, __ATOMIC_SEQ_CST ); proc->ready.pick.pop .lsuccess = 0; 95 69 __atomic_fetch_add( &cltr->ready.threads.migration , proc->ready.threads.migration , __ATOMIC_SEQ_CST ); proc->ready.threads.migration = 0; 96 70 __atomic_fetch_add( &cltr->ready.threads.threads , proc->ready.threads.threads , __ATOMIC_SEQ_CST ); proc->ready.threads.threads = 0; … … 121 95 122 96 if( flags & CFA_STATS_READY_Q ) { 123 double push_len = ((double)ready.push.local.attempt + ready.push.share.attempt + ready.push.extrn.attempt) / (ready.push.local.success + ready.push.share.success + ready.push.extrn.success); 124 double sLcl_len = ready.push.local.success ? ((double)ready.push.local.attempt) / ready.push.local.success : 0; 125 double sOth_len = ready.push.share.success ? ((double)ready.push.share.attempt) / ready.push.share.success : 0; 126 double sExt_len = ready.push.extrn.success ? ((double)ready.push.extrn.attempt) / ready.push.extrn.success : 0; 127 128 double rLcl_len = ready.pop.local .success ? ((double)ready.pop.local .attempt) / ready.pop.local .success : 0; 129 double rHlp_len = ready.pop.help .success ? ((double)ready.pop.help .attempt) / ready.pop.help .success : 0; 130 double rStl_len = ready.pop.steal .success ? ((double)ready.pop.steal .attempt) / ready.pop.steal .success : 0; 131 double rSch_len = ready.pop.search.success ? ((double)ready.pop.search.attempt) / ready.pop.search.success : 0; 97 double push_len = ((double)ready.pick.push.attempt) / ready.pick.push.success; 98 double ext_len = ((double)ready.pick.ext .attempt) / ready.pick.ext .success; 99 double pop_len = ((double)ready.pick.pop .attempt) / ready.pick.pop .success; 100 101 double lpush_len = ((double)ready.pick.push.local) / ready.pick.push.lsuccess; 102 double lext_len = ((double)ready.pick.ext .local) / ready.pick.ext .lsuccess; 103 double lpop_len = ((double)ready.pick.pop .local) / ready.pick.pop .lsuccess; 132 104 133 105 __cfaabi_bits_print_safe( STDOUT_FILENO, 134 106 "----- %s \"%s\" (%p) - Ready Q Stats -----\n" 135 "- totals : %'3" PRIu64 " run, %'3" PRIu64 " schd (%'" PRIu64 "ext, %'" PRIu64 "mig, %'" PRId64 " )\n" 136 "- push avg : %'3.2lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n" 137 "- local : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 138 "- help : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 139 "- steal : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 140 "- search : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 141 "- Idle Slp : %'3" PRIu64 "h, %'3" PRIu64 "c, %'3" PRIu64 "w, %'3" PRIu64 "e\n" 107 "- total threads : %'15" PRIu64 "run, %'15" PRIu64 "schd (%'" PRIu64 "ext, %'" PRIu64 "mig, %'" PRId64 " )\n" 108 "- push avg probe : %'3.2lf, %'3.2lfl (%'15" PRIu64 " attempts, %'15" PRIu64 " locals)\n" 109 "- ext avg probe : %'3.2lf, %'3.2lfl (%'15" PRIu64 " attempts, %'15" PRIu64 " locals)\n" 110 "- pop avg probe : %'3.2lf, %'3.2lfl (%'15" PRIu64 " attempts, %'15" PRIu64 " locals)\n" 111 "- Idle Sleep : %'15" PRIu64 "h, %'15" PRIu64 "c, %'15" PRIu64 "w, %'15" PRIu64 "e\n" 142 112 "\n" 143 113 , type, name, id 144 , ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success 145 , ready.push.local.success + ready.push.share.success + ready.push.extrn.success 146 , ready.push.extrn.success, ready.threads.migration, ready.threads.threads 147 , push_len, sLcl_len, ready.push.local.attempt, sOth_len, ready.push.share.attempt, sExt_len, ready.push.extrn.attempt 148 , rLcl_len, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty 149 , rHlp_len, ready.pop.help .attempt, ready.pop.help .espec, ready.pop.help .elock, ready.pop.help .eempty 150 , rStl_len, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty 151 , rSch_len, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty 114 , ready.pick.pop.success 115 , ready.pick.push.success + ready.pick.ext.success 116 , ready.pick.ext.success, ready.threads.migration, ready.threads.threads 117 , push_len, lpush_len, ready.pick.push.attempt, ready.pick.push.local 118 , ext_len , lext_len , ready.pick.ext .attempt, ready.pick.ext .local 119 , pop_len , lpop_len , ready.pick.pop .attempt, ready.pick.pop .local 152 120 , ready.sleep.halts, ready.sleep.cancels, ready.sleep.wakes, ready.sleep.exits 153 121 ); -
libcfa/src/concurrency/stats.hfa
r665edf40 rc8a0210 16 16 static inline void __print_stats( struct __stats_t *, int, const char *, const char *, void * ) {} 17 17 #else 18 struct __stats_readyQ_pop_t {19 // number of attemps at poping something20 volatile uint64_t attempt;21 18 22 // number of successes at poping 23 volatile uint64_t success; 24 25 // number of attempts failed due to the lock being held 26 volatile uint64_t elock; 27 28 // number of attempts failed due to the queue being empty (lock held) 29 volatile uint64_t eempty; 30 31 // number of attempts failed due to the queue looking empty (lock not held) 32 volatile uint64_t espec; 33 }; 34 35 struct __attribute__((aligned(64))) __stats_readyQ_t { 36 // Push statistic 19 struct __attribute__((aligned(64))) __stats_readQ_t { 37 20 struct { 21 // Push statistic 38 22 struct { 39 // number of attemps at pushing something to preferred queues23 // number of attemps at pushing something 40 24 volatile uint64_t attempt; 41 25 26 // number of successes at pushing 27 volatile uint64_t success; 28 29 // number of attemps at pushing something to preferred queues 30 volatile uint64_t local; 31 42 32 // number of successes at pushing to preferred queues 33 volatile uint64_t lsuccess; 34 } push; 35 36 struct { 37 // number of attemps at pushing something 38 volatile uint64_t attempt; 39 40 // number of successes at pushing 43 41 volatile uint64_t success; 44 }45 // Stats for local queue within cluster46 local,47 42 48 // Stats for non-local queues within cluster49 share,43 // number of attemps at pushing something to preferred queues 44 volatile uint64_t local; 50 45 51 // Stats from outside cluster52 extrn;53 } push;46 // number of successes at pushing to preferred queues 47 volatile uint64_t lsuccess; 48 } ext; 54 49 55 // Pop statistic 56 struct { 57 // pop from local queue 58 __stats_readyQ_pop_t local; 50 // Pop statistic 51 struct { 52 // number of reads of the mask 53 // picking an empty __cfa_readyQ_mask_t counts here 54 // but not as an attempt 55 volatile uint64_t probe; 59 56 60 // pop before looking at local queue61 __stats_readyQ_pop_t help;57 // number of attemps at poping something 58 volatile uint64_t attempt; 62 59 63 // pop from some other queue64 __stats_readyQ_pop_t steal;60 // number of successes at poping 61 volatile uint64_t success; 65 62 66 // pop when searching queues sequentially 67 __stats_readyQ_pop_t search; 68 } pop; 63 // number of attemps at poping something to preferred queues 64 volatile uint64_t local; 69 65 66 // number of successes at poping to preferred queues 67 volatile uint64_t lsuccess; 68 } pop; 69 } pick; 70 70 struct { 71 71 volatile uint64_t migration; … … 119 119 120 120 struct __attribute__((aligned(128))) __stats_t { 121 __stats_read yQ_t ready;121 __stats_readQ_t ready; 122 122 #if defined(CFA_HAVE_LINUX_IO_URING_H) 123 123 __stats_io_t io; -
tests/time.cfa
r665edf40 rc8a0210 10 10 // Created On : Tue Mar 27 17:24:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 16 14:59:53 202113 // Update Count : 3 812 // Last Modified On : Thu Jun 18 18:14:49 2020 13 // Update Count : 37 14 14 // 15 15 … … 53 53 // | "Newfoundland" | getTime( Newfoundland ) 54 54 // | "local" | getTime() 55 // | "local nsec" | timeHiRes()55 // | "local nsec" | getTimeNsec() 56 56 // | "PST" | PST(); // getTime short form 57 57 // sout | nl;
Note:
See TracChangeset
for help on using the changeset viewer.