私は現在、Robert Love の「Linux Kernel Development」を読んでいて、CFS についていくつか質問を受けました。私の質問は、 calc_delta_mine の計算方法です:
delta_exec_weighted= (delta_exec * 重量)/lw->重量
私はそれが2つのステップで行われると思います:
(delta_exec * 1024) の計算:
if (likely(weight > (1UL << SCHED_LOAD_RESOLUTION))) tmp = (u64)delta_exec * scale_load_down(weight); else tmp = (u64)delta_exec;
/lw->weight (または * 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 (Shift right and round) マクロは次の方法で定義されます。
#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 ビットの乗算オーバーフローをどのようにチェックするかを説明できますか? また、この関数のマクロの定義を教えてください((~0UL) ,(1UL << 32))?