Changeset 8834751


Ignore:
Timestamp:
Jun 16, 2020, 12:53:58 PM (18 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast, new-ast-unique-expr
Children:
2073d20
Parents:
d29255c
Message:

Moved statistics to stats.cfa to combine ready Q stats and IO stats

Location:
libcfa/src/concurrency
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/invoke.h

    rd29255c r8834751  
    4848                extern __attribute__((aligned(128))) thread_local struct KernelThreadData {
    4949                        struct $thread    * volatile this_thread;
    50                         struct processor      * volatile this_processor;
     50                        struct processor  * volatile this_processor;
     51                        struct __stats_t  * volatile this_stats;
    5152
    5253                        struct {
  • libcfa/src/concurrency/io.cfa

    rd29255c r8834751  
    135135                void * ring_ptr;
    136136                size_t ring_sz;
    137 
    138                 // Statistics
    139                 #if !defined(__CFA_NO_STATISTICS__)
    140                         struct {
    141                                 struct {
    142                                         volatile unsigned long long int rdy;
    143                                         volatile unsigned long long int csm;
    144                                         volatile unsigned long long int avl;
    145                                         volatile unsigned long long int cnt;
    146                                 } submit_avg;
    147                                 struct {
    148                                         volatile unsigned long long int val;
    149                                         volatile unsigned long long int cnt;
    150                                         volatile unsigned long long int block;
    151                                 } look_avg;
    152                                 struct {
    153                                         volatile unsigned long long int val;
    154                                         volatile unsigned long long int cnt;
    155                                         volatile unsigned long long int block;
    156                                 } alloc_avg;
    157                         } stats;
    158                 #endif
    159137        };
    160138
     
    177155                void * ring_ptr;
    178156                size_t ring_sz;
    179 
    180                 // Statistics
    181                 #if !defined(__CFA_NO_STATISTICS__)
    182                         struct {
    183                                 struct {
    184                                         unsigned long long int val;
    185                                         unsigned long long int slow_cnt;
    186                                         unsigned long long int fast_cnt;
    187                                 } completed_avg;
    188                         } stats;
    189                 #endif
    190157        };
    191158
     
    331298                (this.io->submit){ min(*sq.num, *cq.num) };
    332299
    333                 // Initialize statistics
    334                 #if !defined(__CFA_NO_STATISTICS__)
    335                         this.io->submit_q.stats.submit_avg.rdy = 0;
    336                         this.io->submit_q.stats.submit_avg.csm = 0;
    337                         this.io->submit_q.stats.submit_avg.avl = 0;
    338                         this.io->submit_q.stats.submit_avg.cnt = 0;
    339                         this.io->submit_q.stats.look_avg.val   = 0;
    340                         this.io->submit_q.stats.look_avg.cnt   = 0;
    341                         this.io->submit_q.stats.look_avg.block = 0;
    342                         this.io->submit_q.stats.alloc_avg.val   = 0;
    343                         this.io->submit_q.stats.alloc_avg.cnt   = 0;
    344                         this.io->submit_q.stats.alloc_avg.block = 0;
    345                         this.io->completion_q.stats.completed_avg.val = 0;
    346                         this.io->completion_q.stats.completed_avg.slow_cnt = 0;
    347                         this.io->completion_q.stats.completed_avg.fast_cnt = 0;
    348                 #endif
    349 
    350300                if(!main_cluster) {
    351301                        __kernel_io_finish_start( this );
     
    437387                        __kernel_io_prepare_stop( this );
    438388                }
    439 
    440                 // print statistics
    441                 #if !defined(__CFA_NO_STATISTICS__)
    442                         if(this.print_stats) {
    443                                 with(this.io->submit_q.stats, this.io->completion_q.stats) {
    444                                         double avgrdy = ((double)submit_avg.rdy) / submit_avg.cnt;
    445                                         double avgcsm = ((double)submit_avg.csm) / submit_avg.cnt;
    446                                         double avgavl = ((double)submit_avg.avl) / submit_avg.cnt;
    447 
    448                                         double lavgv = 0;
    449                                         double lavgb = 0;
    450                                         if(look_avg.cnt != 0) {
    451                                                 lavgv = ((double)look_avg.val  ) / look_avg.cnt;
    452                                                 lavgb = ((double)look_avg.block) / look_avg.cnt;
    453                                         }
    454 
    455                                         double aavgv = 0;
    456                                         double aavgb = 0;
    457                                         if(alloc_avg.cnt != 0) {
    458                                                 aavgv = ((double)alloc_avg.val  ) / alloc_avg.cnt;
    459                                                 aavgb = ((double)alloc_avg.block) / alloc_avg.cnt;
    460                                         }
    461 
    462                                         __cfaabi_bits_print_safe( STDOUT_FILENO,
    463                                                 "----- I/O uRing Stats -----\n"
    464                                                 "- total submit calls     : %'15llu\n"
    465                                                 "- avg ready entries      : %'18.2lf\n"
    466                                                 "- avg submitted entries  : %'18.2lf\n"
    467                                                 "- avg available entries  : %'18.2lf\n"
    468                                                 "- total ready search     : %'15llu\n"
    469                                                 "- avg ready search len   : %'18.2lf\n"
    470                                                 "- avg ready search block : %'18.2lf\n"
    471                                                 "- total alloc search     : %'15llu\n"
    472                                                 "- avg alloc search len   : %'18.2lf\n"
    473                                                 "- avg alloc search block : %'18.2lf\n"
    474                                                 "- total wait calls       : %'15llu   (%'llu slow, %'llu fast)\n"
    475                                                 "- avg completion/wait    : %'18.2lf\n",
    476                                                 submit_avg.cnt,
    477                                                 avgrdy,
    478                                                 avgcsm,
    479                                                 avgavl,
    480                                                 look_avg.cnt,
    481                                                 lavgv,
    482                                                 lavgb,
    483                                                 alloc_avg.cnt,
    484                                                 aavgv,
    485                                                 aavgb,
    486                                                 completed_avg.slow_cnt + completed_avg.fast_cnt,
    487                                                 completed_avg.slow_cnt,  completed_avg.fast_cnt,
    488                                                 ((double)completed_avg.val) / (completed_avg.slow_cnt + completed_avg.fast_cnt)
    489                                         );
    490                                 }
    491                         }
    492                 #endif
    493389
    494390                // Shutdown the io rings
     
    578474                // update statistics
    579475                #if !defined(__CFA_NO_STATISTICS__)
    580                         ring.submit_q.stats.submit_avg.rdy += to_submit;
    581                         ring.submit_q.stats.submit_avg.csm += ret;
    582                         ring.submit_q.stats.submit_avg.avl += avail;
    583                         ring.submit_q.stats.submit_avg.cnt += 1;
     476                        __tls_stats()->io.submit_q.stats.submit_avg.rdy += to_submit;
     477                        __tls_stats()->io.submit_q.stats.submit_avg.csm += ret;
     478                        __tls_stats()->io.submit_q.stats.submit_avg.avl += avail;
     479                        __tls_stats()->io.submit_q.stats.submit_avg.cnt += 1;
    584480                #endif
    585481
     
    655551                                // Update statistics
    656552                                #if !defined(__CFA_NO_STATISTICS__)
    657                                         ring.completion_q.stats.completed_avg.val += count;
    658                                         ring.completion_q.stats.completed_avg.slow_cnt += 1;
     553                                        __tls_stats()->io.complete_q.stats.completed_avg.val += count;
     554                                        __tls_stats()->io.complete_q.stats.completed_avg.slow_cnt += 1;
    659555                                #endif
    660556
     
    675571                                // Update statistics
    676572                                #if !defined(__CFA_NO_STATISTICS__)
    677                                         ring.completion_q.stats.completed_avg.val += count;
    678                                         ring.completion_q.stats.completed_avg.slow_cnt += 1;
     573                                        __tls_stats()->io.complete_q.stats.completed_avg.val += count;
     574                                        __tls_stats()->io.complete_q.stats.completed_avg.slow_cnt += 1;
    679575                                #endif
    680576                        }
     
    708604                        // Update statistics
    709605                        #if !defined(__CFA_NO_STATISTICS__)
    710                                 this.ring->completion_q.stats.completed_avg.val += count;
    711                                 this.ring->completion_q.stats.completed_avg.fast_cnt += 1;
     606                                __tls_stats()->io.complete_q.stats.completed_avg.val += count;
     607                                __tls_stats()->io.complete_q.stats.completed_avg.fast_cnt += 1;
    712608                        #endif
    713609
     
    792688                                        // update statistics
    793689                                        #if !defined(__CFA_NO_STATISTICS__)
    794                                                 __atomic_fetch_add( &ring.submit_q.stats.alloc_avg.val,   len,   __ATOMIC_RELAXED );
    795                                                 __atomic_fetch_add( &ring.submit_q.stats.alloc_avg.block, block, __ATOMIC_RELAXED );
    796                                                 __atomic_fetch_add( &ring.submit_q.stats.alloc_avg.cnt,   1,     __ATOMIC_RELAXED );
     690                                                __tls_stats()->io.submit_q.stats.alloc_avg.val   += len;
     691                                                __tls_stats()->io.submit_q.stats.alloc_avg.block += block;
     692                                                __tls_stats()->io.submit_q.stats.alloc_avg.cnt   += 1;
    797693                                        #endif
    798694
     
    847743                        // update statistics
    848744                        #if !defined(__CFA_NO_STATISTICS__)
    849                                 __atomic_fetch_add( &ring.submit_q.stats.look_avg.val,   len,   __ATOMIC_RELAXED );
    850                                 __atomic_fetch_add( &ring.submit_q.stats.look_avg.block, block, __ATOMIC_RELAXED );
    851                                 __atomic_fetch_add( &ring.submit_q.stats.look_avg.cnt,   1,     __ATOMIC_RELAXED );
     745                                __tls_stats()->io.submit_q.stats.look_avg.val   += len;
     746                                __tls_stats()->io.submit_q.stats.look_avg.block += block;
     747                                __tls_stats()->io.submit_q.stats.look_avg.cnt   += 1;
    852748                        #endif
    853749
     
    876772                        // update statistics
    877773                        #if !defined(__CFA_NO_STATISTICS__)
    878                                 ring.submit_q.stats.submit_avg.csm += 1;
    879                                 ring.submit_q.stats.submit_avg.cnt += 1;
     774                                __tls_stats()->io.submit_q.stats.submit_avg.csm += 1;
     775                                __tls_stats()->io.submit_q.stats.submit_avg.cnt += 1;
    880776                        #endif
    881777
  • libcfa/src/concurrency/kernel.cfa

    rd29255c r8834751  
    130130KERNEL_STORAGE(__stack_t,            mainThreadCtx);
    131131KERNEL_STORAGE(__scheduler_RWLock_t, __scheduler_lock);
     132#if !defined(__CFA_NO_STATISTICS__)
     133KERNEL_STORAGE(__stats_t, mainProcStats);
     134#endif
    132135
    133136cluster              * mainCluster;
     
    146149thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) = {
    147150        NULL,                                                                                           // cannot use 0p
     151        NULL,
    148152        NULL,
    149153        { 1, false, false },
     
    268272        #if !defined(__CFA_NO_STATISTICS__)
    269273                print_stats = false;
     274                stats = alloc();
     275                __init_stats( stats );
    270276        #endif
    271277
     
    281287void ^?{}(cluster & this) {
    282288        __kernel_io_shutdown( this, &this == mainCluster );
     289
     290        #if !defined(__CFA_NO_STATISTICS__)
     291                if(this.print_stats) {
     292                        __print_stats( this.stats );
     293                }
     294                free( this.stats );
     295        #endif
    283296
    284297        unregister(this);
     
    357370
    358371        __cfadbg_print_safe(runtime_core, "Kernel : core %p terminated\n", this);
    359 
    360         stats_tls_tally(this->cltr);
    361372}
    362373
     
    479490// It effectively constructs a coroutine by stealing the pthread stack
    480491static void * __invoke_processor(void * arg) {
     492        #if !defined( __CFA_NO_STATISTICS__ )
     493                __stats_t local_stats;
     494                __init_stats( &local_stats );
     495                kernelTLS.this_stats = &local_stats;
     496        #endif
     497
    481498        processor * proc = (processor *) arg;
    482499        kernelTLS.this_processor = proc;
     
    509526        // Main routine of the core returned, the core is now fully terminated
    510527        __cfadbg_print_safe(runtime_core, "Kernel : core %p main ended (%p)\n", proc, &proc->runner);
     528
     529        #if !defined(__CFA_NO_STATISTICS__)
     530                __tally_stats(proc->cltr->stats, &local_stats);
     531        #endif
    511532
    512533        return 0p;
     
    794815        kernelTLS.this_thread    = mainThread;
    795816
     817        #if !defined( __CFA_NO_STATISTICS__ )
     818                kernelTLS.this_stats = (__stats_t *)& storage_mainProcStats;
     819                __init_stats( kernelTLS.this_stats );
     820        #endif
     821
    796822        // Enable preemption
    797823        kernel_start_preemption();
     
    874900//=============================================================================================
    875901static $thread * __halt(processor * this) with( *this ) {
    876         if( do_terminate ) return 0p;
    877 
    878         // First, lock the cluster idle
    879         lock( cltr->idle_lock __cfaabi_dbg_ctx2 );
    880 
    881         // Check if we can find a thread
    882         if( $thread * found = __next_thread( cltr ) ) {
    883                 unlock( cltr->idle_lock );
    884                 return found;
    885         }
    886 
    887         // Move this processor from the active list to the idle list
    888         move_to_front(cltr->procs, cltr->idles, *this);
    889 
    890         // Unlock the idle lock so we don't go to sleep with a lock
    891         unlock    (cltr->idle_lock);
    892 
    893         // We are ready to sleep
    894         __cfadbg_print_safe(runtime_core, "Kernel : Processor %p ready to sleep\n", this);
    895         wait( idle );
    896 
    897         // We have woken up
    898         __cfadbg_print_safe(runtime_core, "Kernel : Processor %p woke up and ready to run\n", this);
    899 
    900         // Get ourself off the idle list
    901         with( *cltr ) {
    902                 lock  (idle_lock __cfaabi_dbg_ctx2);
    903                 move_to_front(idles, procs, *this);
    904                 unlock(idle_lock);
    905         }
     902        // if( do_terminate ) return 0p;
     903
     904        // // First, lock the cluster idle
     905        // lock( cltr->idle_lock __cfaabi_dbg_ctx2 );
     906
     907        // // Check if we can find a thread
     908        // if( $thread * found = __next_thread( cltr ) ) {
     909        //      unlock( cltr->idle_lock );
     910        //      return found;
     911        // }
     912
     913        // // Move this processor from the active list to the idle list
     914        // move_to_front(cltr->procs, cltr->idles, *this);
     915
     916        // // Unlock the idle lock so we don't go to sleep with a lock
     917        // unlock    (cltr->idle_lock);
     918
     919        // // We are ready to sleep
     920        // __cfadbg_print_safe(runtime_core, "Kernel : Processor %p ready to sleep\n", this);
     921        // wait( idle );
     922
     923        // // We have woken up
     924        // __cfadbg_print_safe(runtime_core, "Kernel : Processor %p woke up and ready to run\n", this);
     925
     926        // // Get ourself off the idle list
     927        // with( *cltr ) {
     928        //      lock  (idle_lock __cfaabi_dbg_ctx2);
     929        //      move_to_front(idles, procs, *this);
     930        //      unlock(idle_lock);
     931        // }
    906932
    907933        // Don't check the ready queue again, we may not be in a position to run a thread
     
    911937// Wake a thread from the front if there are any
    912938static bool __wake_one(cluster * this) {
    913         // First, lock the cluster idle
    914         lock( this->idle_lock __cfaabi_dbg_ctx2 );
    915 
    916         // Check if there is someone to wake up
    917         if( !this->idles.head ) {
    918                 // Nope unlock and return false
    919                 unlock( this->idle_lock );
    920                 return false;
    921         }
    922 
    923         // Wake them up
    924         __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this->idles.head);
    925         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    926         post( this->idles.head->idle );
    927 
    928         // Unlock and return true
    929         unlock( this->idle_lock );
    930         return true;
     939        // // First, lock the cluster idle
     940        // lock( this->idle_lock __cfaabi_dbg_ctx2 );
     941
     942        // // Check if there is someone to wake up
     943        // if( !this->idles.head ) {
     944        //      // Nope unlock and return false
     945        //      unlock( this->idle_lock );
     946        //      return false;
     947        // }
     948
     949        // // Wake them up
     950        // __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this->idles.head);
     951        // /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     952        // post( this->idles.head->idle );
     953
     954        // // Unlock and return true
     955        // unlock( this->idle_lock );
     956        // return true;
     957
     958        return false;
    931959}
    932960
    933961// Unconditionnaly wake a thread
    934962static bool __wake_proc(processor * this) {
    935         __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    936 
    937         disable_interrupts();
    938                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    939                 bool ret = post( this->idle );
    940         enable_interrupts( __cfaabi_dbg_ctx );
    941 
    942         return ret;
     963        // __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
     964
     965        // disable_interrupts();
     966        //      /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     967        //      bool ret = post( this->idle );
     968        // enable_interrupts( __cfaabi_dbg_ctx );
     969
     970        // return ret;
     971
     972        return false;
    943973}
    944974
  • libcfa/src/concurrency/kernel.hfa

    rd29255c r8834751  
    5050struct __processor_id_t {
    5151        unsigned id;
     52
     53        #if !defined(__CFA_NO_STATISTICS__)
     54                struct __stats_t * stats;
     55        #endif
    5256};
    5357
     
    165169                volatile size_t count;
    166170        } lanes;
    167 
    168         // Statistics
    169         #if !defined(__CFA_NO_STATISTICS__)
    170                 struct __attribute__((aligned(64))) {
    171                         struct {
    172                                 // Push statistic
    173                                 struct {
    174                                         // number of attemps at pushing something
    175                                         volatile size_t attempt;
    176 
    177                                         // number of successes at pushing
    178                                         volatile size_t success;
    179                                 } push;
    180 
    181                                 // Pop statistic
    182                                 struct {
    183                                         // number of reads of the mask
    184                                         // picking an empty __cfa_readyQ_mask_t counts here
    185                                         // but not as an attempt
    186                                         volatile size_t maskrds;
    187 
    188                                         // number of attemps at poping something
    189                                         volatile size_t attempt;
    190 
    191                                         // number of successes at poping
    192                                         volatile size_t success;
    193                                 } pop;
    194                         } pick;
    195 
    196                         // stats on the "used" struct of the queue
    197                         // tracks average number of queues that are not empty
    198                         // when pushing / poping
    199                         struct {
    200                                 volatile size_t value;
    201                                 volatile size_t count;
    202                         } used;
    203                 } global_stats;
    204 
    205         #endif
    206171};
    207172
     
    242207        #if !defined(__CFA_NO_STATISTICS__)
    243208                bool print_stats;
     209                struct __stats_t * stats;
    244210        #endif
    245211};
  • libcfa/src/concurrency/kernel_private.hfa

    rd29255c r8834751  
    2020
    2121#include "alarm.hfa"
     22#include "stats.hfa"
    2223
    2324
     
    237238// Statics call at the end of each thread to register statistics
    238239#if !defined(__CFA_NO_STATISTICS__)
    239 void stats_tls_tally(struct cluster * cltr);
    240 #else
    241 static inline void stats_tls_tally(struct cluster * cltr) {}
     240static inline struct __stats_t * __tls_stats() {
     241        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     242        /* paranoid */ verify( kernelTLS.this_stats );
     243        return kernelTLS.this_stats;
     244}
    242245#endif
    243246
  • libcfa/src/concurrency/preemption.cfa

    rd29255c r8834751  
    269269// reserved for future use
    270270static void timeout( struct __processor_id_t * id, $thread * this ) {
     271        #if !defined( __CFA_NO_STATISTICS__ )
     272                kernelTLS.this_stats = this->curr_cluster->stats;
     273        #endif
    271274        __unpark( id, this __cfaabi_dbg_ctx2 );
    272275}
  • libcfa/src/concurrency/ready_queue.cfa

    rd29255c r8834751  
    535535//=======================================================================
    536536
    537 // Thread local mirror of ready queue statistics
    538 #if !defined(__CFA_NO_STATISTICS__)
    539 static __attribute__((aligned(128))) thread_local struct {
    540         struct {
    541                 struct {
    542                         size_t attempt;
    543                         size_t success;
    544                 } push;
    545                 struct {
    546                         size_t maskrds;
    547                         size_t attempt;
    548                         size_t success;
    549                 } pop;
    550         } pick;
    551         struct {
    552                 size_t value;
    553                 size_t count;
    554         } used;
    555 } tls = {
    556         /* pick */{
    557                 /* push */{ 0, 0 },
    558                 /* pop  */{ 0, 0, 0 },
    559         },
    560         /* used */{ 0, 0 }
    561 };
    562 #endif
    563 
    564 //-----------------------------------------------------------------------
    565 
    566537void ?{}(__ready_queue_t & this) with (this) {
    567538
     
    572543        lanes.count = 4;
    573544        snzi{ log2( lanes.count / 8 ) };
    574 
    575         #if !defined(__CFA_NO_STATISTICS__)
    576                 global_stats.pick.push.attempt = 0;
    577                 global_stats.pick.push.success = 0;
    578                 global_stats.pick.pop .maskrds = 0;
    579                 global_stats.pick.pop .attempt = 0;
    580                 global_stats.pick.pop .success = 0;
    581 
    582                 global_stats.used.value = 0;
    583                 global_stats.used.count = 0;
    584         #endif
    585545}
    586546
     
    611571
    612572                #if !defined(__CFA_NO_STATISTICS__)
    613                         tls.pick.push.attempt++;
     573                        __tls_stats()->ready.pick.push.attempt++;
    614574                #endif
    615575
     
    638598        // Update statistics
    639599        #if !defined(__CFA_NO_STATISTICS__)
    640                 tls.pick.push.success++;
     600                __tls_stats()->ready.pick.push.success++;
    641601        #endif
    642602
     
    649609static struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j) with (cltr->ready_queue) {
    650610        #if !defined(__CFA_NO_STATISTICS__)
    651                 tls.pick.pop.attempt++;
     611                __tls_stats()->ready.pick.pop.attempt++;
    652612        #endif
    653613
     
    692652        // Update statistics
    693653        #if !defined(__CFA_NO_STATISTICS__)
    694                 tls.pick.pop.success++;
     654                __tls_stats()->ready.pick.pop.success++;
    695655        #endif
    696656
     
    895855        ready_mutate_unlock( last_size );
    896856}
    897 
    898 //-----------------------------------------------------------------------
    899 
    900 #if !defined(__CFA_NO_STATISTICS__)
    901 void stats_tls_tally(struct cluster * cltr) with (cltr->ready_queue) {
    902         __atomic_fetch_add( &global_stats.pick.push.attempt, tls.pick.push.attempt, __ATOMIC_SEQ_CST );
    903         __atomic_fetch_add( &global_stats.pick.push.success, tls.pick.push.success, __ATOMIC_SEQ_CST );
    904         __atomic_fetch_add( &global_stats.pick.pop .maskrds, tls.pick.pop .maskrds, __ATOMIC_SEQ_CST );
    905         __atomic_fetch_add( &global_stats.pick.pop .attempt, tls.pick.pop .attempt, __ATOMIC_SEQ_CST );
    906         __atomic_fetch_add( &global_stats.pick.pop .success, tls.pick.pop .success, __ATOMIC_SEQ_CST );
    907 
    908         __atomic_fetch_add( &global_stats.used.value, tls.used.value, __ATOMIC_SEQ_CST );
    909         __atomic_fetch_add( &global_stats.used.count, tls.used.count, __ATOMIC_SEQ_CST );
    910 }
    911 #endif
  • libcfa/src/concurrency/stats.cfa

    rd29255c r8834751  
     1#include <stdint.h>
     2#include <stdlib.hfa>
     3
     4#include <unistd.h>                                                             // STDERR_FILENO
     5#include "bits/debug.hfa"
     6#include "stats.hfa"
     7
     8#if !defined(__CFA_NO_STATISTICS__)
     9        void __init_stats( struct __stats_t * stats ) {
     10                stats->ready.pick.push.attempt = 0;
     11                stats->ready.pick.push.success = 0;
     12                stats->ready.pick.pop .probe   = 0;
     13                stats->ready.pick.pop .attempt = 0;
     14                stats->ready.pick.pop .success = 0;
     15
     16                #if defined(HAVE_LINUX_IO_URING_H)
     17                        stats->io.submit_q.submit_avg.rdy = 0;
     18                        stats->io.submit_q.submit_avg.csm = 0;
     19                        stats->io.submit_q.submit_avg.avl = 0;
     20                        stats->io.submit_q.submit_avg.cnt = 0;
     21                        stats->io.submit_q.look_avg.val   = 0;
     22                        stats->io.submit_q.look_avg.cnt   = 0;
     23                        stats->io.submit_q.look_avg.block = 0;
     24                        stats->io.submit_q.alloc_avg.val   = 0;
     25                        stats->io.submit_q.alloc_avg.cnt   = 0;
     26                        stats->io.submit_q.alloc_avg.block = 0;
     27                        stats->io.complete_q.completed_avg.val = 0;
     28                        stats->io.complete_q.completed_avg.slow_cnt = 0;
     29                        stats->io.complete_q.completed_avg.fast_cnt = 0;
     30                #endif
     31        }
     32
     33        void __tally_stats( struct __stats_t * cltr, struct __stats_t * proc ) {
     34                __atomic_fetch_add( &cltr->ready.pick.push.attempt, proc->ready.pick.push.attempt, __ATOMIC_SEQ_CST );
     35                __atomic_fetch_add( &cltr->ready.pick.push.success, proc->ready.pick.push.success, __ATOMIC_SEQ_CST );
     36                __atomic_fetch_add( &cltr->ready.pick.pop .probe  , proc->ready.pick.pop .probe  , __ATOMIC_SEQ_CST );
     37                __atomic_fetch_add( &cltr->ready.pick.pop .attempt, proc->ready.pick.pop .attempt, __ATOMIC_SEQ_CST );
     38                __atomic_fetch_add( &cltr->ready.pick.pop .success, proc->ready.pick.pop .success, __ATOMIC_SEQ_CST );
     39
     40                #if defined(HAVE_LINUX_IO_URING_H)
     41                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.rdy          , proc->io.submit_q.submit_avg.rdy          , __ATOMIC_SEQ_CST );
     42                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.csm          , proc->io.submit_q.submit_avg.csm          , __ATOMIC_SEQ_CST );
     43                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.avl          , proc->io.submit_q.submit_avg.avl          , __ATOMIC_SEQ_CST );
     44                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.cnt          , proc->io.submit_q.submit_avg.cnt          , __ATOMIC_SEQ_CST );
     45                        __atomic_fetch_add( &cltr->io.submit_q.look_avg.val            , proc->io.submit_q.look_avg.val            , __ATOMIC_SEQ_CST );
     46                        __atomic_fetch_add( &cltr->io.submit_q.look_avg.cnt            , proc->io.submit_q.look_avg.cnt            , __ATOMIC_SEQ_CST );
     47                        __atomic_fetch_add( &cltr->io.submit_q.look_avg.block          , proc->io.submit_q.look_avg.block          , __ATOMIC_SEQ_CST );
     48                        __atomic_fetch_add( &cltr->io.submit_q.alloc_avg.val           , proc->io.submit_q.alloc_avg.val           , __ATOMIC_SEQ_CST );
     49                        __atomic_fetch_add( &cltr->io.submit_q.alloc_avg.cnt           , proc->io.submit_q.alloc_avg.cnt           , __ATOMIC_SEQ_CST );
     50                        __atomic_fetch_add( &cltr->io.submit_q.alloc_avg.block         , proc->io.submit_q.alloc_avg.block         , __ATOMIC_SEQ_CST );
     51                        __atomic_fetch_add( &cltr->io.complete_q.completed_avg.val     , proc->io.complete_q.completed_avg.val     , __ATOMIC_SEQ_CST );
     52                        __atomic_fetch_add( &cltr->io.complete_q.completed_avg.slow_cnt, proc->io.complete_q.completed_avg.slow_cnt, __ATOMIC_SEQ_CST );
     53                        __atomic_fetch_add( &cltr->io.complete_q.completed_avg.fast_cnt, proc->io.complete_q.completed_avg.fast_cnt, __ATOMIC_SEQ_CST );
     54                #endif
     55        }
     56
     57        void __print_stats( struct __stats_t * stats ) {
     58
     59                double push_sur = (100.0 * ((double)stats->ready.pick.push.success) / stats->ready.pick.push.attempt);
     60                double pop_sur  = (100.0 * ((double)stats->ready.pick.pop .success) / stats->ready.pick.pop .attempt);
     61
     62                double push_len = ((double)stats->ready.pick.push.attempt) / stats->ready.pick.push.success;
     63                double pop_len  = ((double)stats->ready.pick.pop .attempt) / stats->ready.pick.pop .success;
     64
     65                #if defined(HAVE_LINUX_IO_URING_H)
     66                        double avgrdy = ((double)submit_avg.rdy) / submit_avg.cnt;
     67                        double avgcsm = ((double)submit_avg.csm) / submit_avg.cnt;
     68                        double avgavl = ((double)submit_avg.avl) / submit_avg.cnt;
     69
     70                        double lavgv = 0;
     71                        double lavgb = 0;
     72                        if(look_avg.cnt != 0) {
     73                                lavgv = ((double)look_avg.val  ) / look_avg.cnt;
     74                                lavgb = ((double)look_avg.block) / look_avg.cnt;
     75                        }
     76
     77                        double aavgv = 0;
     78                        double aavgb = 0;
     79                        if(alloc_avg.cnt != 0) {
     80                                aavgv = ((double)alloc_avg.val  ) / alloc_avg.cnt;
     81                                aavgb = ((double)alloc_avg.block) / alloc_avg.cnt;
     82                        }
     83                #endif
     84
     85                __cfaabi_bits_print_safe( STDOUT_FILENO,
     86                        "----- Ready Q Stats -----\n"
     87                        "- total threads run      : %'15lu\n"
     88                        "- total threads scheduled: %'15lu\n"
     89                        "- push average probe len : %'18.2lf, %'18.2lf%% (%'15lu attempts)\n"
     90                        "- pop  average probe len : %'18.2lf, %'18.2lf%% (%'15lu attempts)\n"
     91                        #if defined(HAVE_LINUX_IO_URING_H)
     92                                "\n"
     93                                "----- I/O Stats -----\n"
     94                                "- total submit calls     : %'15llu\n"
     95                                "- avg ready entries      : %'18.2lf\n"
     96                                "- avg submitted entries  : %'18.2lf\n"
     97                                "- avg available entries  : %'18.2lf\n"
     98                                "- total ready search     : %'15llu\n"
     99                                "- avg ready search len   : %'18.2lf\n"
     100                                "- avg ready search block : %'18.2lf\n"
     101                                "- total alloc search     : %'15llu\n"
     102                                "- avg alloc search len   : %'18.2lf\n"
     103                                "- avg alloc search block : %'18.2lf\n"
     104                                "- total wait calls       : %'15llu   (%'llu slow, %'llu fast)\n"
     105                                "- avg completion/wait    : %'18.2lf\n"
     106                        #endif
     107                        , stats->ready.pick.pop.success
     108                        , stats->ready.pick.push.success
     109                        , push_len, push_sur, stats->ready.pick.push.attempt
     110                        , pop_len , pop_sur , stats->ready.pick.pop .attempt
     111                        #if defined(HAVE_LINUX_IO_URING_H)
     112                                , submit_avg.cnt
     113                                , avgrdy
     114                                , avgcsm
     115                                , avgavl
     116                                , look_avg.cnt
     117                                , lavgv
     118                                , lavgb
     119                                , alloc_avg.cnt
     120                                , aavgv
     121                                , aavgb
     122                                , completed_avg.slow_cnt + completed_avg.fast_cnt
     123                                , completed_avg.slow_cnt,  completed_avg.fast_cnt
     124                                , ((double)completed_avg.val) / (completed_avg.slow_cnt + completed_avg.fast_cnt)
     125                        #endif
     126                );
     127        }
     128#endif
Note: See TracChangeset for help on using the changeset viewer.