如何让 llvm 使用 'OR' 指令进行加速

How to get llvm to use the 'OR' instruction for speedup

我有一些 C 代码基本上可以归结为:

    *p_Bool3 = *p_Bool1 || *p_Bool2;

其中 p_Bool1、p_Bool2 和 p_Bool3 为“bool *”。

clang++ 为我提供了使用 O2 的 X86 程序集(O3 没有区别,我只是使用 O2,因为那是实际项目中使用的):

mov eax, dword ptr [esp + 12]
    mov edx, dword ptr [esp + 4]
    mov cl, 1
    cmp byte ptr [edx], 0
    je  LBB1_1
    mov byte ptr [eax], cl
    ret
LBB1_1: 
    mov ecx, dword ptr [esp + 8]
    mov cl, byte ptr [ecx]
    mov byte ptr [eax], cl
    ret

实际程序有点复杂,有一堆 ob get 和 set 函数以及一些重载运算符,但它基本上是使用 O2 的相同汇编代码:

001de515  mov         al, 0x01 
001de517  mov         ecx, dword ptr ds:[edi+0x00000628] 
001de51d  cmp         byte ptr ds:[ecx], 0x00000000 
001de520  jne         0x001DE52E 
001de522  mov         eax, dword ptr ds:[edi+0x0000065C] 
001de528  cmp         byte ptr ds:[eax], 0x00000000 
001de52b  setne       al 
001de52e  mov         ecx, dword ptr ds:[edi+0x000005EC] 
001de534  mov         byte ptr ds:[ecx], al 

现在我有一些参考代码在相同的 hardware/system 上运行速度提高了 75%,如下所示:

0100121e  lea         ebx, dword ptr ds:[esi+0x10280005] 
01001224  mov         al, byte ptr ds:[ebx] 
01001226  lea         ebx, dword ptr ds:[esi+0x10280006] 
0100122c  or          al, byte ptr ds:[ebx] 
0100122e  lea         ebx, dword ptr ds:[esi+0x10280004] 
01001234  mov         byte ptr ds:[ebx], al 

如何让 clang 仅使用 'or' 指令并更快?

您是否尝试过使用 *p_Bool3 = *p_Bool1 | *p_Bool2 中的 OR 运算符?编译器无法自行生成它,因为如果 p_Bool1 为真,则不允许取消引用 p_Bool2

如果您不能在此处使用 | 运算符,也应该首先手动解引用指针,告诉编译器允许这样做:

bool tmp1 = *p_Bool1, tmp2 = *p_Bool2;

*p_Bool3 = tmp1 || tmp2;

|| 运算符一起使用的 left/right 表达式被 延迟计算 。由于间接会导致副作用(例如页面错误、硬件影响),编译器需要使用条件来防止副作用在不应该发生的时候发生。

要避免此问题,您可以使用 | 运算符。 Here 是一个例子。