Ignore:
Timestamp:
Apr 19, 2021, 5:07:16 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
59f3f61, 665edf40, ddd473f
Parents:
4aa495f
Message:

Changed stats to make sense with relaxed fifo and work stealing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/ready_queue.cfa

    r4aa495f rd2fadeb  
    3535static const size_t cache_line_size = 64;
    3636
     37#if !defined(__CFA_NO_STATISTICS__)
     38        #define __STATS(...) __VA_ARGS__
     39#else
     40        #define __STATS(...)
     41#endif
     42
    3743// No overriden function, no environment variable, no define
    3844// fall back to a magic number
     
    5258#endif
    5359
     60static inline struct $thread * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats));
     61static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats));
     62static inline struct $thread * search(struct cluster * cltr);
    5463static 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);
    57 static inline struct $thread * search(struct cluster * cltr);
    5864
    5965
     
    269275
    270276                        #if !defined(__CFA_NO_STATISTICS__)
    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                                 }
     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++;
    279280                        #endif
    280281
     
    302303                // Update statistics
    303304                #if !defined(__CFA_NO_STATISTICS__)
    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                         }
     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++;
    312308                #endif
    313309        }
     
    334330                        [j, localj] = idx_from_r(rj, preferred);
    335331
    336                         #if !defined(__CFA_NO_STATISTICS__)
    337                                 if(locali && localj) {
    338                                         __tls_stats()->ready.pick.pop.local++;
    339                                 }
    340                         #endif
    341 
    342332                        i %= count;
    343333                        j %= count;
    344334
    345335                        // try popping from the 2 picked lists
    346                         struct $thread * thrd = try_pop(cltr, i, j);
     336                        struct $thread * thrd = try_pop(cltr, i, j __STATS(, *(locali || localj ? &__tls_stats()->ready.pop.local : &__tls_stats()->ready.pop.help)));
    347337                        if(thrd) {
    348                                 #if !defined(__CFA_NO_STATISTICS__)
    349                                         if( locali || localj ) __tls_stats()->ready.pick.pop.lsuccess++;
    350                                 #endif
    351338                                return thrd;
    352339                        }
     
    374361                unsigned i;
    375362                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                        #endif
     367
    376368                        if(unlikely(external)) {
    377369                                i = __tls_rand() % lanes.count;
     
    398390                        // Unlock and return
    399391                        __atomic_unlock( &lanes.data[i].lock );
     392                #endif
     393
     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++;
    400397                #endif
    401398
     
    422419                }
    423420                else if(lanes.tscs[proc->rdq.target].tv < proc->rdq.cutoff) {
    424                         $thread * t = try_pop(cltr, proc->rdq.target);
     421                        $thread * t = try_pop(cltr, proc->rdq.target __STATS(, __tls_stats()->ready.pop.help));
    425422                        proc->rdq.target = -1u;
    426423                        if(t) return t;
     
    429426                for(READYQ_SHARD_FACTOR) {
    430427                        unsigned i = proc->rdq.id + (--proc->rdq.itr % READYQ_SHARD_FACTOR);
    431                         if($thread * t = try_pop(cltr, i)) return t;
     428                        if($thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;
    432429                }
    433430                return 0p;
     
    437434                for(25) {
    438435                        unsigned i = __tls_rand() % lanes.count;
    439                         $thread * t = try_pop(cltr, i);
     436                        $thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal));
    440437                        if(t) return t;
    441438                }
     
    453450//-----------------------------------------------------------------------
    454451// try to pop from a lane given by index w
    455 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w) with (cltr->ready_queue) {
     452static 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
    456455        // Get relevant elements locally
    457456        __intrusive_lane_t & lane = lanes.data[w];
    458457
    459458        // If list looks empty retry
    460         if( is_empty(lane) ) return 0p;
     459        if( is_empty(lane) ) {
     460                __STATS( stats.espec++; )
     461                return 0p;
     462        }
    461463
    462464        // If we can't get the lock retry
    463         if( !__atomic_try_acquire(&lane.lock) ) return 0p;
     465        if( !__atomic_try_acquire(&lane.lock) ) {
     466                __STATS( stats.elock++; )
     467                return 0p;
     468        }
    464469
    465470        // If list is empty, unlock and retry
    466471        if( is_empty(lane) ) {
    467472                __atomic_unlock(&lane.lock);
     473                __STATS( stats.eempty++; )
    468474                return 0p;
    469475        }
     
    480486
    481487        // Update statistics
    482         #if !defined(__CFA_NO_STATISTICS__)
    483                 __tls_stats()->ready.pick.pop.success++;
    484         #endif
     488        __STATS( stats.success++; )
    485489
    486490        #if defined(USE_WORK_STEALING)
     
    501505        for(i; count) {
    502506                unsigned idx = (offset + i) % count;
    503                 struct $thread * thrd = try_pop(cltr, idx);
     507                struct $thread * thrd = try_pop(cltr, idx __STATS(, __tls_stats()->ready.pop.search));
    504508                if(thrd) {
    505509                        return thrd;
     
    539543//-----------------------------------------------------------------------
    540544// Given 2 indexes, pick the list with the oldest push an try to pop from it
    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 
     545static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) {
    546546        // Pick the bet list
    547547        int w = i;
     
    550550        }
    551551
    552         return try_pop(cltr, w);
     552        return try_pop(cltr, w __STATS(, stats));
    553553}
    554554
Note: See TracChangeset for help on using the changeset viewer.