免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1759 | 回复: 2
打印 上一主题 下一主题

请问一个看不懂的函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-21 10:30 |只看该作者 |倒序浏览
在CFS的sched_fair.c中有这么一个函数
根据注释和网上的讲解,它计算的应该是delta_exec * weight / lw->weight,可能只是近似计算
但是我数学不好,怎么都看不懂这个简单的函数,不知道哪位能帮忙解释一下
我把该函数和里面用到的定义一并贴出来了,假设是32位机器

# define WMULT_CONST    (~0UL)
#define WMULT_SHIFT    32
#define SRR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
/*
&nbsp;* delta *= weight / lw
&nbsp;*/

static unsigned long
calc_delta_mine(unsigned long delta_exec, unsigned long weight,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct load_weight *lw)
{
&nbsp;&nbsp;&nbsp;&nbsp;u64 tmp;

&nbsp;&nbsp;&nbsp;&nbsp;if (!lw->inv_weight) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lw->inv_weight = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/ (lw->weight+1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;tmp = (u64)delta_exec * weight;
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Check whether we'd overflow the 64-bit multiplication:
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;if (unlikely(tmp > WMULT_CONST))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = SRR(SRR(tmp, WMULT_SHIFT/2) * lw->inv_weight,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WMULT_SHIFT/2);
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = SRR(tmp * lw->inv_weight, WMULT_SHIFT);

&nbsp;&nbsp;&nbsp;&nbsp;return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
}

论坛徽章:
0
2 [报告]
发表于 2010-01-21 14:43 |只看该作者
太深奥了,看不懂,应该都是为了防止相乘之后越界,再一个就是用移位来近似代替除法.

论坛徽章:
0
3 [报告]
发表于 2010-01-21 15:07 |只看该作者
原帖由 emmoblin 于 2010-1-21 14:43 发表
太深奥了,看不懂,应该都是为了防止相乘之后越界,再一个就是用移位来近似代替除法.


看来看去,觉得好像就这么两句话是关键
tmp = (u64)delta_exec * weight;
tmp = SRR(tmp * lw->inv_weight, WMULT_SHIFT);
上面的inv_weight好像是2^32/lw->weight的近似值,
但是又不明白为什么这个近似值要用下面这个式子来算,
1 + (WMULT_CONST-lw->weight/2)/ (lw->weight+1)
这个式子也没有避免除法啊。

其他代码好像确实向楼上所说都是在避免溢出
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP