很久以前,我使用这个简单的x86汇编技巧来获得0或1作为浮点数比较的结果:
fld [value1]
fcom [value2]
fnstsw ax
mov al, ah
and eax, 1
如果比较结果仅影响从一组2个值中选择值,则此技巧允许避免分支 . 在Pentium时代它很快,现在它可能不会那么快,但谁知道呢 .
现在我主要使用C并使用Intel C Compiler或GCC C Compiler进行编译 .
有人可以请帮助将此代码重写为2个内置汇编程序风格(Intel和GCC) .
所需的函数原型是:inline int compareDoublesIndexed(const double value1,const double value2)
也许使用SSE2操作可能更有效率 . 你的观点?
我试过这个:
__asm__(
"fcomq %2, %0\n"
"fnstsw %ax\n"
"fsubq %2, %0\n"
"andq $L80, %eax\n"
"shrq $5, %eax\n"
"fmulq (%3,%eax), %0\n"
: "=f" (penv)
: "0" (penv), "F" (env), "r" (c)
: "eax" );
但是我在Intel C Compiler中遇到错误:浮点输出约束必须指定一个寄存器 .
1 回答
正如你所提到的,自奔腾日以来情况发生了变化:
SSE现在是浮点而不是x87的首选指令集,即使对于标量运算也是如此
优化编译器现在非常好
因此,首先检查编译器生成的内容,您可能会感到惊喜 . 我在下面的代码中用
-O3
尝试了gfcmp.cpp:
这是编译器生成的
这就是它的含义
因此编译器通过使用
seta
指令避免了条件分支(如果结果在上面,则设置字节为'1',否则为'0') .