gcc 内联汇编中的 min
Posted
技术标签:
【中文标题】gcc 内联汇编中的 min【英文标题】:min in inline assembly in gcc 【发布时间】:2014-07-05 15:58:03 【问题描述】:至于今天我使用了我自己的min()
函数(用于float
和int
)
那是基于 if 但今天我知道 x86 有一些操作数
对于分钟 - 这是
MINSS - 操作数的最小值
我认为如果基于min()
例程是反效果的,并且
我对优化非常小心,所以我想重写我自己的
使用一些内联汇编例程进入minss
版本,
我想找到最有效的版本 gcc 内联汇编看起来像
我需要类似的东西
int min(int a, int b)
// minss a, b
//return
对于int
和float
,使用minss
操作码并且具有最少的序言和
尾声
或者只使用库版本会更快?虽然我想 不使用库 min/max 并尽可能快地使用它
【问题讨论】:
我认为只使用编译器的 sse-enable 标志要好得多。编译器比我们知道的信息多得多。 我不知道为什么这个问题会得到 2 票反对。 +1 【参考方案1】:下面是min
对int
s 和float
s 最有效的实现:
int
min_int(int a, int b)
return a < b ? a : b;
float
min_float(float a, float b)
return a < b ? a : b;
“但是,”你惊呼道,“那些会有条件跳转!”没有。这是gcc -S -O2
的输出:
min_int:
cmpl %edi, %esi
movl %edi, %eax
cmovle %esi, %eax
ret
min_float:
minss %xmm1, %xmm0
ret
对于int
s,你得到一个条件移动,对于float
s,你得到minss
,因为编译器非常聪明。不需要内联 ASM!
编辑:如果您仍然对如何使用内联汇编感到好奇,这里有一个示例(适用于 gcc):
float
min_float_asm(float a, float b)
float result = a;
asm ("minss %1, %0" : "+x" (result) : "x" (b));
return result;
x
约束表示“任何 SSE 寄存器”,"+x"
表示将读取和写入该值,而 "x"
表示只读。
【讨论】:
@user2214913 我添加了一个示例。 在您的内联汇编中,result
和 b
是否应该同时在输入列表和输出列表中?它们被用作 r/w..
minss
的源操作数可以是内存或寄存器,因此您可以使用"xm" (b)
为编译器提供选项。 (但是由于这样的限制,clang 有时会无缘无故地溢出到内存中。)
是的,但是如果你想让编译器更好地优化代码,就这样做return a < b ? a : b;
:)【参考方案2】:
好吧,我建议不要进行这种微优化。如果你想这样做,GCC 有一些__builtin_*
函数。一个是v4sf __builtin_ia32_minss (v4sf, v4sf)
。还有其他 min*
内置插件,请查看文档。
更新
要获得更多可移植性,您可能需要查看Intel Intrinsics Guide。 GCC 和 Clang 通常也支持这些函数。
【讨论】:
了解一些内在函数,但询问了内联汇编 @user2214913:我认为这是XY problem 的一个实例,因此我建议要么完全避免这种微优化,要么使用内部函数。以上是关于gcc 内联汇编中的 min的主要内容,如果未能解决你的问题,请参考以下文章