【问题标题】:Why doesn't likely and unlikely macros have any effect on ARM assembly code?为什么可能和不太可能的宏对 ARM 汇编代码没有任何影响?
【发布时间】:2019-10-17 15:35:52
【问题描述】:

下面的例子来自https://kernelnewbies.org/FAQ/LikelyUnlikely

#include <stdio.h>
#define likely(x)    __builtin_expect(!!(x), 1)
#define unlikely(x)  __builtin_expect(!!(x), 0)

int main(char *argv[], int argc)
{
   int a;

   /* Get the value from somewhere GCC can't optimize */
   a = atoi (argv[1]);

   if (likely (a == 2))
      a++;
   else
      a--;

   printf ("%d\n", a);

   return 0;
}

并用arm gcc 8.2 compiler 编译它https://godbolt.org/z/IC0aif

在原始链接中,他们已经针对X86进行了测试,如果将likely(在上面代码中的if条件中)替换为unlikely,则汇编输出不同,这表明编译器对分支预测进行了优化.

但是当我为 ARM (arm-gcc -O2) 编译上述代码时,我看不出汇编代码有什么不同。下面是两种情况下 ARM 程序集的输出 - likelyunlikely

main:
        push    {r4, lr}
        ldr     r0, [r0, #4]
        bl      atoi
        cmp     r0, #2
        subne   r1, r0, #1
        moveq   r1, #3
        ldr     r0, .L6
        bl      printf
        mov     r0, #0
        pop     {r4, pc}
.L6:
        .word   .LC0
.LC0:
        .ascii  "%d\012\000"

为什么编译器不对 ARM 的分支预测进行优化?

【问题讨论】:

  • 这可能取决于确切的目标 ARM CPU,因为有些具有浅管道且没有分支预测单元。
  • 没有分支预测,因为没有分支。 ARM 允许您对大多数指令设置条件。例如,subne 仅在最后一次比较“不等于”时才进行减法运算,而 moveq 仅在最后一次比较为“等于”时移动文字值。
  • 我没这么说。在这里,条件动作非常简单。对于更复杂的条件,将需要分支,并且可能/不太可能会影响代码生成。 (在任何平台上)实际产生的差异有多大是另一个问题。
  • 1) 没有理由认为这会改善任何目标的代码输出。 2) 没有理由假设编译器无法解决这个问题。
  • 为什么要否决这个问题?这个问题是真实而明确的。

标签: c gcc linux-kernel arm likely-unlikely


【解决方案1】:

正如@rici 所说,您的代码很简单,可以通过条件指令来实现。您可以看到不同之处,例如,如果您调用在不同编译单元中实现的函数:

#define likely(x)    __builtin_expect(!!(x), 1)
#define unlikely(x)  __builtin_expect(!!(x), 0)

// only forward declarations:
void foo();
void bar();

int main(char *argv[], int argc)
{
   if (likely (argc == 2))
      foo();
   else
      bar();
}

likely 更改为unlikely 会切换ifelse 分支的顺序,对于ARM 和x86:https://godbolt.org/z/UDzvf0。如果这真的产生影响,可能取决于您正在运行的硬件,您是否第一次调用该函数(否则,CPU 内部分支预测可能比指令的顺序具有更高的影响),可能还有许多其他东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多