如果运行得更快,为什么还要嵌套?

问题描述 投票:0回答:1

我发现嵌套的

if
比序列化的
if
运行得更快,这让我很困惑。

我有一段代码需要运行1亿次:

if(b8 < 254) {
    if(b8 < 252)
        return data[b8];
    return random_bit() ? data[b8] : -data[b8];
}

b8
是一个
uint8_t
随机数,
random_bit()
返回 0-1 随机数。该片段将通过 2 个 if 判断返回一些值,我意识到我可以将其重写为

if(b8 < 252)
    return data[b8];
if(b8 < 254)
    return random_bit() ? data[b8] : -data[b8];

现在,

return data[b8]
只需要1个if判断。然而,我注意到程序在重复 1 亿次时速度慢了大约 0.01 秒。由于某种原因,我需要这段代码运行得更快,即使它是 0.01 秒。那么我是否误解了这段代码?

顺便说一句,代码是用

-Ofast
编译的,汇编代码对我来说太复杂了,无法理解。汇编代码:

.L2:    ; nested
    cmpb    $-3, %bl
    ja  .L3
    movzbl  %bl, %r12d
    cmpb    $-5, %bl
    ja  .L4
    movsbl  sample_val.8(%r12), %ebx
    addq    $8, %rsp
    movl    %ebx, %eax
    popq    %rbx
    popq    %rbp
    popq    %r12
    popq    %r13
    ret

.L2:    ; serialized
    cmpb    $-5, %r14b
    jbe .L24
    movl    %r14d, %ebx                 ; inline random_bit()
    movl    $8, %r12d
    movq    cnt.7(%rip), %rdx
    movabsq $4611686018427387904, %r13
    andl    $1, %ebx
    cmpb    $-3, %r14b
    ja  .L19
    testq   %rdx, %rdx
    je  .L6
    shrq    %rdx
    movq    b64.6(%rip), %rax
    movq    %rdx, cnt.7(%rip)

GCC 只是将它们编译成不同的东西,尽管我认为它们是等效的。

c optimization
1个回答
0
投票

这实际上取决于

b8
的值最常见。该代码区分了三种情况:

  1. b8 < 252
  2. 252 <= b8 < 254
  3. b8 >= 254

现在考虑两个版本对每种情况进行的比较次数。

“嵌套”代码执行 (1) 2 次比较 (2) 2 次比较 (3) 1 次比较。

“序列化”代码执行 (1) 1 次比较 (2) 2 次比较 (3) 2 次比较。

因此“嵌套”代码优化了

b8 >= 254
的情况,而“序列化”代码优化了
b8 < 252
的情况。

© www.soinside.com 2019 - 2024. All rights reserved.