相关疑难解决方法(0)

在x86汇编中将寄存器设置为零的最佳方法是什么:xor,mov或?

以下所有说明都做同样的事情:设置%eax为零.哪种方式最佳(需要最少的机器周期)?

xorl   %eax, %eax
mov    $0, %eax
andl   $0, %eax
Run Code Online (Sandbox Code Playgroud)

optimization performance x86 assembly micro-optimization

109
推荐指数
1
解决办法
4万
查看次数

为什么MSVC在执行此位测试之前会发出无用的MOVSX?

在MSVC 2013中编译以下代码,64位版本构建,/O2优化:

while (*s == ' ' || *s == ',' || *s == '\r' || *s == '\n') {
    ++s;
}
Run Code Online (Sandbox Code Playgroud)

我得到了以下代码 - 使用64位寄存器作为带有bt(位测试)指令的查找表,它具有非常酷的优化.

    mov     rcx, 17596481020928             ; 0000100100002400H
    npad    5
$LL82@myFunc:
    movzx   eax, BYTE PTR [rsi]
    cmp     al, 44                          ; 0000002cH
    ja      SHORT $LN81@myFunc
    movsx   rax, al
    bt      rcx, rax
    jae     SHORT $LN81@myFunc
    inc     rsi
    jmp     SHORT $LL82@myFunc
$LN81@myFunc:
    ; code after loop...
Run Code Online (Sandbox Code Playgroud)

但我的问题是:movsx rax, al第一个分支后的目的是什么?

首先,我们从字符串中加载一个字节rax并对其进行零扩展:

movzx eax, BYTE …
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly x86-64 visual-studio

15
推荐指数
2
解决办法
918
查看次数

Clang生成的7次比较比8次比较糟糕的代码

clang能够将许多小整数的==比较转换为一条大SIMD指令,这让我很感兴趣,但是后来我注意到了一些奇怪的事情。当我进行7次比较时,Clang生成了“更差”的代码(在我的业余评估中),而当我进行8次比较时,Clang生成了该代码。

bool f1(short x){
    return (x==-1) | (x == 150) |
           (x==5) | (x==64) | 
           (x==15) | (x==223) | 
           (x==42) | (x==47);
}

bool f2(short x){
    return (x==-1) | (x == 150) |
           (x==5) | (x==64) | 
           (x==15) | (x==223) | 
           (x==42);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是这是一个很小的性能错误,或者clang有一个很好的理由不想引入虚拟比较(即假装与7个值之一进行额外的比较),并在代码中使用一个更多的常量来实现它。

Godbolt链接在这里

# clang(trunk) -O2 -march=haswell
f1(short):
    vmovd   xmm0, edi
    vpbroadcastw    xmm0, xmm0             # set1(x)
    vpcmpeqw        xmm0, xmm0, xmmword ptr [rip + .LCPI0_0]  # 16 bytes = 8 shorts
    vpacksswb       xmm0, xmm0, xmm0
    vpmovmskb       eax, …
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly clang compiler-optimization

5
推荐指数
1
解决办法
110
查看次数