Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/cluster.hfa

    r5f6b2c2 r33e4968e  
    1818#include "device/cpu.hfa"
    1919#include "kernel/private.hfa"
    20 #include "math.hfa"
    2120
    2221#include <limits.h>
     
    2423#include "clock.hfa"
    2524
    26 #if   defined(READYQ_USE_LINEAR_AVG)
    27 
    28 // no conversion needed in this case
    29 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { return intsc; }
    30 
    31 // warn normally all ints
    32 #define warn_large_before warnf( !strict || old_avg < 33_000_000_000, "Suspiciously large previous average: %'llu (%llx), %'ldms \n", old_avg, old_avg, program()`ms )
    33 #define warn_large_after warnf( !strict || ret < 33_000_000_000, "Suspiciously large new average after %'ldms cputime: %'llu (%llx) from %'llu-%'llu (%'llu, %'llu) and %'llu\n", program()`ms, ret, ret, currtsc, intsc, new_val, new_val / 1000000, old_avg )
    34 
    35 // 8X linear factor is just 8 * x
    36 #define AVG_FACTOR( x ) (8 * (x))
    37 
    38 #elif defined(READYQ_USE_LOGDBL_AVG)
    39 
    40 // convert to log2 scale but using double
    41 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2(intsc); }
    42 
    43 #define warn_large_before warnf( !strict || old_avg < 35.0, "Suspiciously large previous average: %'lf, %'ldms \n", old_avg, program()`ms )
    44 #define warn_large_after warnf( !strict || ret < 35.3, "Suspiciously large new average after %'ldms cputime: %'lf from %'llu-%'llu (%'llu, %'llu) and %'lf\n", program()`ms, ret, currtsc, intsc, new_val, new_val / 1000000, old_avg ); \
    45 verify(ret >= 0)
    46 
    47 // 8X factor in logscale is log2(8X) = log2(8) + log2(X) = 3 + log2(X)
    48 #define AVG_FACTOR( x ) (3.0 + (x))
    49 
    50 // we need to overload the __atomic_load_n because they don't support double
    51 static inline double __atomic_load_n(volatile double * ptr, int mem) {
    52         volatile uint64_t * uptr = (volatile uint64_t *)ptr;
    53         _Static_assert(sizeof(*uptr) == sizeof(*ptr));
    54         uint64_t ret = 0;
    55         ret = __atomic_load_n(uptr, mem);
    56         uint64_t *rp = &ret;
    57         double ret = *(volatile double *)rp;
    58         /* paranoid */ verify( ret == 0 || ret > 3e-100 );
    59         return ret;
    60 }
    61 
    62 // we need to overload the __atomic_store_n because they don't support double
    63 static inline void __atomic_store_n(volatile double * ptr, double val, int mem) {
    64         /* paranoid */ verify( val == 0 || val > 3e-100 );
    65         volatile uint64_t * uptr = (volatile uint64_t *)ptr;
    66         _Static_assert(sizeof(*uptr) == sizeof(*ptr));
    67         uint64_t * valp = (uint64_t *)&val;
    68         __atomic_store_n(uptr, *valp, mem);
    69 }
    70 
    71 #elif defined(READYQ_USE_LOGDBL_AVG)
    72 
    73 //convert to log2 scale but with fix point u32.32 values
    74 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { return ulog2_32_32(tsc); }
    75 
    76 // 8X factor, +3 in logscale (see above) is + 0x3.00000000
    77 #define AVG_FACTOR( x ) (0x3_00000000ull + (x))
    78 
    79 #else
    80 #error must pick a scheme for averaging
    81 #endif
    82 
    8325//-----------------------------------------------------------------------
    8426// Calc moving average based on existing average, before and current time.
    85 static inline __readyQ_avg_t moving_average(unsigned long long currtsc, unsigned long long intsc, __readyQ_avg_t old_avg, bool strict) {
     27static inline unsigned long long moving_average(unsigned long long currtsc, unsigned long long instsc, unsigned long long old_avg, bool strict) {
    8628        (void)strict; // disable the warning around the fact this is unused in release.
    87         /* paranoid */ warn_large_before;
     29        /* paranoid */ warnf( !strict || old_avg < 33_000_000_000, "Suspiciously large previous average: %'llu (%llx), %'ldms \n", old_avg, old_avg, program()`ms );
    8830
    89         const unsigned long long new_val = currtsc > intsc ? currtsc - intsc : 0;
    90         const __readyQ_avg_t total_weight = 16;
    91         const __readyQ_avg_t new_weight   = 12;
    92         const __readyQ_avg_t old_weight = total_weight - new_weight;
    93         const __readyQ_avg_t ret = ((new_weight * __to_readyQ_avg(new_val)) + (old_weight * old_avg)) / total_weight;
     31        const unsigned long long new_val = currtsc > instsc ? currtsc - instsc : 0;
     32        const unsigned long long total_weight = 16;
     33        const unsigned long long new_weight   = 4;
     34        const unsigned long long old_weight = total_weight - new_weight;
     35        const unsigned long long ret = ((new_weight * new_val) + (old_weight * old_avg)) / total_weight;
    9436
    95         /* paranoid */ warn_large_after;
     37        /* paranoid */ warnf( !strict || ret < 33_000_000_000, "Suspiciously large new average after %'ldms cputime: %'llu (%llx) from %'llu-%'llu (%'llu, %'llu) and %'llu\n", program()`ms, ret, ret, currtsc, instsc, new_val, new_val / 1000000, old_avg );
    9638        return ret;
    9739}
     
    10042        if (ts_next == ULLONG_MAX) return;
    10143        unsigned long long now = rdtscl();
    102         __readyQ_avg_t pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);
     44        unsigned long long pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);
    10345        __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED);
    10446        __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma, strict), __ATOMIC_RELAXED);
     
    10850// Calc age a timestamp should be before needing help.
    10951forall(Data_t * | { unsigned long long ts(Data_t & this); })
    110 static inline __readyQ_avg_t calc_cutoff(
     52static inline unsigned long long calc_cutoff(
    11153        const unsigned long long ctsc,
    11254        unsigned procid,
     
    11860) {
    11961        unsigned start = procid;
    120         __readyQ_avg_t max = 0;
     62        unsigned long long max = 0;
    12163        for(i; shard_factor) {
    12264                unsigned long long ptsc = ts(data[start + i]);
    12365                if(ptsc != ULLONG_MAX) {
    12466                        /* paranoid */ verify( start + i < count );
    125                         __readyQ_avg_t avg = moving_average(ctsc, ptsc, tscs[start + i].t.ma, strict);
    126                         if(avg > max) max = avg;
     67                        unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].t.ma, strict);
     68                        if(tsc > max) max = tsc;
    12769                }
    12870        }
    129         return AVG_FACTOR( max );
     71        return 8 * max;
    13072}
    13173
Note: See TracChangeset for help on using the changeset viewer.