相关疑难解决方法(0)

Linux内核中可能/不太可能的宏如何工作以及它们的好处是什么?

我一直在挖掘Linux内核的某些部分,发现这样的调用:

if (unlikely(fd < 0))
{
    /* Do something */
}
Run Code Online (Sandbox Code Playgroud)

要么

if (likely(!err))
{
    /* Do something */
}
Run Code Online (Sandbox Code Playgroud)

我找到了它们的定义:

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)
Run Code Online (Sandbox Code Playgroud)

我知道它们是为了优化,但它们是如何工作的?使用它们可以预期性能/尺寸减少多少?至少在瓶颈代码中(当然在用户空间中)是否值得麻烦(并且可能失去可移植性).

linux gcc linux-kernel likely-unlikely

331
推荐指数
6
解决办法
13万
查看次数

如何强制GCC假定浮点表达式为非负数?

在某些情况下,您知道某个浮点表达式将始终为非负数。例如,计算一个矢量的长度时,一个做sqrt(a[0]*a[0] + ... + a[N-1]*a[N-1])(NB:我知道的std::hypot,这是不相关的问题),并且平方根下表达显然是非负的。但是,GCC 为以下输出以下程序集sqrt(x*x)

        mulss   xmm0, xmm0
        pxor    xmm1, xmm1
        ucomiss xmm1, xmm0
        ja      .L10
        sqrtss  xmm0, xmm0
        ret
.L10:
        jmp     sqrtf
Run Code Online (Sandbox Code Playgroud)

也就是说,它将结果x*x与零进行比较,如果结果为非负数,则执行sqrtss指令,否则调用sqrtf

因此,我的问题是:如何强制GCC假定该x*x值始终为非负值,从而跳过比较和sqrtf调用,而无需编写内联汇编?

我想强调的是,我对本地解决方案感兴趣,而不是像-ffast-math-fno-math-errno或那样做-ffinite-math-only(尽管确实可以解决问题,这要归功于ks1322,harold和Eric Postpischil的评论)。

此外,“强制将GCC假定x*x为非负数”应解释为assert(x*x >= 0.f),因此这也排除了x*xNaN 的情况。

我可以使用特定于编译器,特定于平台,特定于CPU等的解决方案。

c++ floating-point assembly gcc micro-optimization

57
推荐指数
3
解决办法
2529
查看次数