Changeset 815943f for libcfa/src/concurrency/kernel
- Timestamp:
- Oct 5, 2022, 10:10:59 PM (23 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 265e460
- Parents:
- ae151cf (diff), 0deeaad (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- libcfa/src/concurrency/kernel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/cluster.cfa
rae151cf r815943f 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
rae151cf r815943f 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) { 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 25 83 //----------------------------------------------------------------------- 26 84 // 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) {85 static inline __readyQ_avg_t moving_average(unsigned long long currtsc, unsigned long long intsc, __readyQ_avg_t old_avg, bool strict) { 28 86 (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 );87 /* paranoid */ warn_large_before; 30 88 31 const unsigned long long new_val = currtsc > in stsc ? currtsc - instsc : 0;32 const unsigned long longtotal_weight = 16;33 const unsigned long long new_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;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; 36 94 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 );95 /* paranoid */ warn_large_after; 38 96 return ret; 39 97 } … … 42 100 if (ts_next == ULLONG_MAX) return; 43 101 unsigned long long now = rdtscl(); 44 unsigned long longpma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED);102 __readyQ_avg_t pma = __atomic_load_n(&tscs[ idx ].t.ma, __ATOMIC_RELAXED); 45 103 __atomic_store_n(&tscs[ idx ].t.tv, ts_next, __ATOMIC_RELAXED); 46 104 __atomic_store_n(&tscs[ idx ].t.ma, moving_average(now, ts_prev, pma, strict), __ATOMIC_RELAXED); … … 50 108 // Calc age a timestamp should be before needing help. 51 109 forall(Data_t * | { unsigned long long ts(Data_t & this); }) 52 static inline unsigned long longcalc_cutoff(110 static inline __readyQ_avg_t calc_cutoff( 53 111 const unsigned long long ctsc, 54 112 unsigned procid, … … 60 118 ) { 61 119 unsigned start = procid; 62 unsigned long longmax = 0;120 __readyQ_avg_t max = 0; 63 121 for(i; shard_factor) { 64 122 unsigned long long ptsc = ts(data[start + i]); 65 123 if(ptsc != ULLONG_MAX) { 66 124 /* 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;125 __readyQ_avg_t avg = moving_average(ctsc, ptsc, tscs[start + i].t.ma, strict); 126 if(avg > max) max = avg; 69 127 } 70 128 } 71 return 8 * max;129 return AVG_FACTOR( max ); 72 130 } 73 131 -
libcfa/src/concurrency/kernel/private.hfa
rae151cf r815943f 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.