gpt4 book ai didi

c++ - 如何在 gcc 和 VS 中强制使用 cmov

转载 作者:太空狗 更新时间:2023-10-29 19:39:12 26 4
gpt4 key购买 nike

我有这个简单的二进制搜索成员函数,其中 lastIndexnIterxi 是类成员:

uint32 scalar(float z) const
{
uint32 lo = 0;
uint32 hi = lastIndex;
uint32 n = nIter;
while (n--) {
int mid = (hi + lo) >> 1;
// defining this if-else assignment as below cause VS2015
// to generate two cmov instructions instead of a branch
if( z < xi[mid] )
hi = mid;
if ( !(z < xi[mid]) )
lo = mid;
}
return lo;
}

gcc 和 VS 2015 都用代码流分支来翻译内部循环:
000000013F0AA778  movss       xmm0,dword ptr [r9+rax*4]  
000000013F0AA77E comiss xmm0,xmm1
000000013F0AA781 jbe Tester::run+28h (013F0AA788h)
000000013F0AA783 mov r8d,ecx
000000013F0AA786 jmp Tester::run+2Ah (013F0AA78Ah)
000000013F0AA788 mov edx,ecx
000000013F0AA78A mov ecx,r8d

有没有办法在不编写内联汇编程序的情况下说服他们使用 1 条 comiss 指令和 2 条 cmov 指令?

如果没有,有人可以建议如何为此编写 gcc 汇编程序模板吗?

请注意,我知道存在二进制搜索算法的变体,其中编译器很容易生成无分支代码,但这不是问题。

谢谢

最佳答案

正如评论中所说,没有简单的方法可以强制您提出要求,尽管最近(> 4.4)版本的 gcc 似乎已经像您所说的那样对其进行了优化。 编辑 :有趣的是, gcc 6 series seems to use a branchgcc 5gcc 7 系列不同,后者使用两个 cmov

通常的 __builtin_expect 可能无法插入 gcc 使用 cmov ,因为 cmov 在难以预测比较结果时通常很方便,而 __builtin_expect 告诉编译器可能的结果是什么 - 所以你只需将它插入错的方向。

尽管如此,如果您发现此优化非常重要,您的编译器版本通常会出错,并且出于某种原因您无法使用 PGO 帮助它,相关的 gcc 程序集模板应该是这样的:

    __asm__ (
"comiss %[xi_mid],%[z]\n"
"cmovb %[mid],%[hi]\n"
"cmovae %[mid],%[lo]\n"
: [hi] "+r"(hi), [lo] "+r"(lo)
: [mid] "rm"(mid), [xi_mid] "xm"(xi[mid]), [z] "x"(z)
: "cc"
);

使用的约束是:
  • hilo 都在“写入”变量列表中,带有 +r 约束,因为 cmov 只能使用寄存器作为目标操作数,我们有条件地只覆盖其中之一(我们不能使用 = ,因为它意味着该值总是覆盖,因此编译器可以自由地为我们提供与当前目标寄存器不同的目标寄存器,并在我们的 asm 块之后使用它来引用该变量);
  • mid 在“读取”列表中,rm 作为 cmov 可以将寄存器或内存操作数作为输入值;
  • xi[mid]z 在“读”列表中;
  • z 具有特殊的 x 约束,意思是“任何 SSE 寄存器”(ucomiss 第一个操作数需要);
  • xi[mid]xm ,因为第二个 ucomiss 操作数允许内存操作;考虑到 zxi[mid] 之间的选择,我选择了最后一个作为直接从内存中获取的更好候选者,因为 z 已经在寄存器中(由于 System V 调用约定 - 并且无论如何都会在迭代之间缓存) 和 xi[mid] 仅用于此比较;
  • cc(FLAGS 寄存器)在“clobber”列表中——我们只破坏标志,没有别的。
  • 关于c++ - 如何在 gcc 和 VS 中强制使用 cmov,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44754267/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com