Changeset 31c967b for libcfa/src/concurrency/kernel
- Timestamp:
- Oct 3, 2022, 4:37:59 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- d1cd4c4
- Parents:
- 890f67a
- Location:
- libcfa/src/concurrency/kernel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/cluster.cfa
r890f67a r31c967b 221 221 static const unsigned __readyq_single_shard = 2; 222 222 223 void ?{}(__timestamp_t & this) { this.t.tv = 0; this.t.ma = 0; } 224 void ^?{}(__timestamp_t &) {} 225 223 226 //----------------------------------------------------------------------- 224 227 // Check that all the intrusive queues in the data structure are still consistent -
libcfa/src/concurrency/kernel/cluster.hfa
r890f67a r31c967b 18 18 #include "device/cpu.hfa" 19 19 #include "kernel/private.hfa" 20 #include "math.hfa" 20 21 21 22 #include <limits.h> … … 23 24 #include "clock.hfa" 24 25 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) { 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 double c = 3e-100; 59 /* paranoid */ verify( ret == 0 || ret > 3e-100 ); 60 return ret; 61 } 62 63 // we need to overload the __atomic_store_n because they don't support double 64 static inline void __atomic_store_n(volatile double * ptr, double val, int mem) { 65 /* paranoid */ verify( val == 0 || val > 3e-100 ); 66 volatile uint64_t * uptr = (volatile uint64_t *)ptr; 67 _Static_assert(sizeof(*uptr) == sizeof(*ptr)); 68 uint64_t * valp = (uint64_t *)&val; 69 __atomic_store_n(uptr, *valp, mem); 70 } 71 72 #elif defined(READYQ_USE_LOGDBL_AVG) 73 74 //convert to log2 scale but with fix point u32.32 values 75 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { return ulog2_32_32(tsc); } 76 77 // 8X factor, +3 in logscale (see above) is + 0x3.00000000 78 #define AVG_FACTOR( x ) (0x3_00000000ull + (x)) 79 80 #else 81 #error must pick a scheme for averaging 82 #endif 83 25 84 //----------------------------------------------------------------------- 26 85 // Calc moving average based on existing average, before and current time. 27 static inline unsigned long long moving_average(unsigned long long currtsc, unsigned long long instsc, unsigned long longold_avg, bool strict) {86 static inline __readyQ_avg_t moving_average(unsigned long long currtsc, unsigned long long intsc, __readyQ_avg_t old_avg, bool strict) { 28 87 (void)strict; // disable the warning around the fact this is unused in release. 29 /* paranoid */ warn f( !strict || old_avg < 33_000_000_000, "Suspiciously large previous average: %'llu (%llx), %'ldms \n", old_avg, old_avg, program()`ms );88 /* paranoid */ warn_large_before; 30 89 31 const unsigned long long new_val = currtsc > in stsc ? currtsc - instsc : 0;32 const unsigned long longtotal_weight = 16;33 const unsigned long longnew_weight = 4;34 const unsigned long longold_weight = total_weight - new_weight;35 const unsigned long long ret = ((new_weight * new_val) + (old_weight * old_avg)) / total_weight;90 const unsigned long long new_val = currtsc > intsc ? currtsc - intsc : 0; 91 const __readyQ_avg_t total_weight = 16; 92 const __readyQ_avg_t new_weight = 4; 93 const __readyQ_avg_t old_weight = total_weight - new_weight; 94 const __readyQ_avg_t ret = ((new_weight * __to_readyQ_avg(new_val)) + (old_weight * old_avg)) / total_weight; 36 95 37 /* paranoid */ warn f( !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 /* paranoid */ warn_large_after; 38 97 return ret; 39 98 } … … 42 101 if (ts_next == ULLONG_MAX) return; 43 102 unsigned long long now = rdtscl(); 44 unsigned long longpma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);103 __readyQ_avg_t pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED); 45 104 __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED); 46 105 __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma, strict), __ATOMIC_RELAXED); … … 50 109 // Calc age a timestamp should be before needing help. 51 110 forall(Data_t * | { unsigned long long ts(Data_t & this); }) 52 static inline unsigned long longcalc_cutoff(111 static inline __readyQ_avg_t calc_cutoff( 53 112 const unsigned long long ctsc, 54 113 unsigned procid, … … 60 119 ) { 61 120 unsigned start = procid; 62 unsigned long longmax = 0;121 __readyQ_avg_t max = 0; 63 122 for(i; shard_factor) { 64 123 unsigned long long ptsc = ts(data[start + i]); 65 124 if(ptsc != ULLONG_MAX) { 66 125 /* paranoid */ verify( start + i < count ); 67 unsigned long long tsc= moving_average(ctsc, ptsc, tscs[start + i].t.ma, strict);68 if( tsc > max) max = tsc;126 __readyQ_avg_t avg = moving_average(ctsc, ptsc, tscs[start + i].t.ma, strict); 127 if(avg > max) max = avg; 69 128 } 70 129 } 71 return 8 * max;130 return AVG_FACTOR( max ); 72 131 } 73 132 -
libcfa/src/concurrency/kernel/private.hfa
r890f67a r31c967b 49 49 #endif 50 50 51 // #define READYQ_USE_LINEAR_AVG 52 #define READYQ_USE_LOGDBL_AVG 53 // #define READYQ_USE_LOGINT_AVG 54 55 #if defined(READYQ_USE_LINEAR_AVG) 56 typedef unsigned long long __readyQ_avg_t; 57 #elif defined(READYQ_USE_LOGDBL_AVG) 58 typedef double __readyQ_avg_t; 59 #elif defined(READYQ_USE_LOGDBL_AVG) 60 typedef unsigned long long __readyQ_avg_t; 61 #else 62 #error must pick a scheme for averaging 63 #endif 64 51 65 //----------------------------------------------------------------------------- 52 66 // Scheduler 67 union __attribute__((aligned(64))) __timestamp_t { 68 struct { 69 volatile unsigned long long tv; 70 volatile __readyQ_avg_t ma; 71 } t; 72 char __padding[192]; 73 }; 74 53 75 extern "C" { 54 76 void disable_interrupts() OPTIONAL_THREAD;
Note: See TracChangeset
for help on using the changeset viewer.