- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel/cluster.hfa (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/cluster.hfa
r5f6b2c2 r33e4968e 18 18 #include "device/cpu.hfa" 19 19 #include "kernel/private.hfa" 20 #include "math.hfa"21 20 22 21 #include <limits.h> … … 24 23 #include "clock.hfa" 25 24 26 #if defined(READYQ_USE_LINEAR_AVG)27 28 // no conversion needed in this case29 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { return intsc; }30 31 // warn normally all ints32 #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 * x36 #define AVG_FACTOR( x ) (8 * (x))37 38 #elif defined(READYQ_USE_LOGDBL_AVG)39 40 // convert to log2 scale but using double41 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 double51 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 double63 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 values74 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.0000000077 #define AVG_FACTOR( x ) (0x3_00000000ull + (x))78 79 #else80 #error must pick a scheme for averaging81 #endif82 83 25 //----------------------------------------------------------------------- 84 26 // 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_told_avg, bool strict) {27 static inline unsigned long long moving_average(unsigned long long currtsc, unsigned long long instsc, unsigned long long old_avg, bool strict) { 86 28 (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 ); 88 30 89 const unsigned long long new_val = currtsc > in tsc ? currtsc - intsc : 0;90 const __readyQ_avg_ttotal_weight = 16;91 const __readyQ_avg_t new_weight = 12;92 const __readyQ_avg_told_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; 94 36 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 ); 96 38 return ret; 97 39 } … … 100 42 if (ts_next == ULLONG_MAX) return; 101 43 unsigned long long now = rdtscl(); 102 __readyQ_avg_tpma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);44 unsigned long long pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED); 103 45 __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED); 104 46 __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma, strict), __ATOMIC_RELAXED); … … 108 50 // Calc age a timestamp should be before needing help. 109 51 forall(Data_t * | { unsigned long long ts(Data_t & this); }) 110 static inline __readyQ_avg_tcalc_cutoff(52 static inline unsigned long long calc_cutoff( 111 53 const unsigned long long ctsc, 112 54 unsigned procid, … … 118 60 ) { 119 61 unsigned start = procid; 120 __readyQ_avg_tmax = 0;62 unsigned long long max = 0; 121 63 for(i; shard_factor) { 122 64 unsigned long long ptsc = ts(data[start + i]); 123 65 if(ptsc != ULLONG_MAX) { 124 66 /* 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; 127 69 } 128 70 } 129 return AVG_FACTOR( max );71 return 8 * max; 130 72 } 131 73
Note:
See TracChangeset
for help on using the changeset viewer.