【发布时间】:2012-08-15 07:58:40
【问题描述】:
我在一个运行了大约 2^26 次的循环中有一些关键的分支代码。分支预测不是最优的,因为m 是随机的。我将如何删除分支,可能使用按位运算符?
bool m;
unsigned int a;
const unsigned int k = ...; // k >= 7
if(a == 0)
a = (m ? (a+1) : (k));
else if(a == k)
a = (m ? 0 : (a-1));
else
a = (m ? (a+1) : (a-1));
这里是gcc -O3生成的相关程序集:
.cfi_startproc
movl 4(%esp), %edx
movb 8(%esp), %cl
movl (%edx), %eax
testl %eax, %eax
jne L15
cmpb $1, %cl
sbbl %eax, %eax
andl $638, %eax
incl %eax
movl %eax, (%edx)
ret
L15:
cmpl $639, %eax
je L23
testb %cl, %cl
jne L24
decl %eax
movl %eax, (%edx)
ret
L23:
cmpb $1, %cl
sbbl %eax, %eax
andl $638, %eax
movl %eax, (%edx)
ret
L24:
incl %eax
movl %eax, (%edx)
ret
.cfi_endproc
【问题讨论】:
-
在开始之前,您可能需要确保您关心的编译器实际上无法将这些优化为条件移动。
-
0
-
@Eric 是的,0
-
我很惊讶 GCC 不能将内部分支变成条件移动。你这里的那些比this question 中的那个要简单得多,
-O3可以完成这项工作。 -
貌似基本是
a = a + (m?1:-1) % k;一个二元 LUT 可以修复的分支。还是我的负模数错误...?
标签: c++ optimization bit-manipulation