gcc 内联汇编中的 min

Posted

技术标签:

【中文标题】gcc 内联汇编中的 min【英文标题】:min in inline assembly in gcc 【发布时间】:2014-07-05 15:58:03 【问题描述】:

至于今天我使用了我自己的min() 函数(用于floatint) 那是基于 if 但今天我知道 x86 有一些操作数 对于分钟 - 这是

MINSS - 操作数的最小值

我认为如果基于min() 例程是反效果的,并且 我对优化非常小心,所以我想重写我自己的 使用一些内联汇编例程进入minss 版本,

我想找到最有效的版本 gcc 内联汇编看起来像

我需要类似的东西

int min(int a, int b)

  // minss a, b
   //return 

对于intfloat,使用minss 操作码并且具有最少的序言和 尾声

或者只使用库版本会更快?虽然我想 不使用库 min/max 并尽可能快地使用它

【问题讨论】:

我认为只使用编译器的 sse-enable 标志要好得多。编译器比我们知道的信息多得多。 我不知道为什么这个问题会得到 2 票反对。 +1 【参考方案1】:

下面是minints 和floats 最有效的实现:

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

对于ints,你得到一个条件移动,对于floats,你得到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 我添加了一个示例。 在您的内联汇编中,resultb 是否应该同时在输入列表和输出列表中?它们被用作 r/w.. minss 的源操作数可以是内存或寄存器,因此您可以使用"xm" (b) 为编译器提供选项。 (但是由于这样的限制,clang 有时会无缘无故地溢出到内存中。) 是的,但是如果你想让编译器更好地优化代码,就这样做return a &lt; b ? a : b; :)【参考方案2】:

好吧,我建议不要进行这种微优化。如果你想这样做,GCC 有一些__builtin_* 函数。一个是v4sf __builtin_ia32_minss (v4sf, v4sf)。还有其他 min* 内置插件,请查看文档。

更新

要获得更多可移植性,您可能需要查看Intel Intrinsics Guide。 GCC 和 Clang 通常也支持这些函数。

【讨论】:

了解一些内在函数,但询问了内联汇编 @user2214913:我认为这是XY problem 的一个实例,因此我建议要么完全避免这种微优化,要么使用内部函数。

以上是关于gcc 内联汇编中的 min的主要内容,如果未能解决你的问题,请参考以下文章

GCC 内联汇编中的标签

GCC内联汇编中的C数组?

这个 GCC 内联汇编中的参数列表有啥问题?

ARM嵌入式开发中的GCC内联汇编__asm__

GCC 内联汇编到 IAR 内联汇编

使用内联汇编器从 GCC 中的共享库调用函数