繁体   English   中英

可以使用`__builtin_expect`影响程序语义吗?

[英]Can using `__builtin_expect` affect program semantics?

海湾合作委员会(和锵也),提供这种__builtin_expect人类辅助的分支预测,为解释在这里 非正式地,人们通过以下方式解释其语义:“编译器只是无条件地处理指定的分支,如果条件应该与指示的不同,则会发生昂贵的回滚”。

但如果我有一段代码如下:

if (__builtin_expect(p != 0, 1)) // line 1
  p->access_object();            // line 2

如果我按字面意思处理上面的非正式解释,编译器只需执行第2行而不等待第1行中的条件计算,因此如果指针恰好为空,则会导致未定义的行为(空指针解除引用)。

我的问题是,如果我使用__builtin_expect ,我仍然得到保证,我的防御性检查有效吗? 如果是这样的话,如果我在防御性检查中使用__builtin_expect作为上述内容,我会获得任何运行时间的好处吗?

(注意:我这样使用__builtin_expect目的是为了获得p非空的情况下的最大性能,代价是减速(甚至是数量级) p为空的情况;即使后者案件经常出现。)

不,builtin_expect不会影响无竞赛计划的语义。

特别是,如果该代码具有无法撤消的副作用,则编译器不得发出执行if块主体的代码。 除了性能之外,代码必须“好像”不使用builtin_expect

对于您的具体示例:

if (__builtin_expect(p != 0, 1)) // line 1
  p->access_object();            // line 2

如果p为null,则无法取消引用。 那么在这种情况下, builtin_expect什么意义呢? 它能做的最多就是告诉编译器“ p可能不是null,所以可能会调用access_object() 。” 如果access_object()的定义是inline ,编译器可能会尝试内联它,而如果您说“ p可能为null”,编译器可能会决定最好不要在此调用站点内联access_object()的代码,因为它不太可能被使用。

事实上,这导致在实践中非直观地使用了builtin_expect :你可以用来表示“这段代码是慢速路径”,而不管它是多么“可能”。 作为一个简单的例子,服务器程序可能会这样做:

if (__builtin_expect(is_allowed(user, request), 1))
    process(request);
else
    reject(request);

即使我们发现50%的请求是非法的并且将被拒绝,我们仍可能决定标记可能采取的“快乐路径”,因为我们不关心减缓拒绝。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM