我正在閱讀Robert Love的「Linux Kernel Development」,並且我收到了一些關於CFS的問題。 我的問題是calc_delta_mine如何計算:calc_delta_mine函數的說明
delta_exec_weighted =(delta_exec *重)/ LW->重
我猜它是由兩個步驟完成:
計算(delta_exec * 1024 ):
if (likely(weight > (1UL << SCHED_LOAD_RESOLUTION))) tmp = (u64)delta_exec * scale_load_down(weight); else tmp = (u64)delta_exec;
計算/ LW->重量(或* LW-> inv_weight):
if (!lw->inv_weight) { unsigned long w = scale_load_down(lw->weight); if (BITS_PER_LONG > 32 && unlikely(w >= WMULT_CONST)) lw->inv_weight = 1; else if (unlikely(!w)) lw->inv_weight = WMULT_CONST; else lw->inv_weight = WMULT_CONST/w; } /* * Check whether we'd overflow the 64-bit multiplication: */ if (unlikely(tmp > WMULT_CONST)) tmp = SRR(SRR(tmp, WMULT_SHIFT/2) * lw->inv_weight, WMULT_SHIFT/2); else tmp = SRR(tmp * lw->inv_weight, WMULT_SHIFT); return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
的SRR(右移和圓)宏通過定義:
#define SRR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
而其他的宏定義:
#if BITS_PER_LONG == 32
# define WMULT_CONST (~0UL)
#else
# define WMULT_CONST (1UL << 32)
#endif
#define WMULT_SHIFT 32
可有人請解釋如何完全SRR的工作原理以及如何檢查64位乘法溢出? 請解釋此函數中MACROS的定義((〜0UL),(1UL < < 32))?
謝謝。所以如果我再看看SRR宏,我明白'(1UL <<((y)-1))是'2 ^(y-1)',並且'((x)+(1UL << (y)-1)))是'x + 2 ^(y-1)'。那麼最後一部分是取得結果並將其轉換成「>>(y)」以將其從32.32恢復爲原始表示? – arkadish
'>>(y)'是2 * y *的* floor劃分。 'SRR'只對整數有效;它不關心結果是否爲32.32。'calc_delta_mine'使用它來計算32.32數字。 – nneonneo
看起來tmp是整數形式:'tmp =(u64)delta_exec * scale_load_down(weight);'當'lw-> inv_weight = WMULT_CONST/w'爲32.32形式時。我認爲通過將乘以32 >>的乘法運算轉換爲整數形式,這種做法更有意義,因爲vruntime是一個整數,不應該表示爲32.32。 – arkadish