【问题标题】:inline assembler direct double to long long conversion内联汇编器直接 double 到 long long 转换
【发布时间】:2012-11-30 16:48:39
【问题描述】:

由于优化原因,我考虑直接调用(使用内联汇编程序) 到函数“fldl”和“拳头”。遗憾的是我不知道如何运行它,因为我不是汇编程序中的神。

我没有比这更进一步:

double* input;         
long long output;

__asm fldl input;      
__asm fist output;

【问题讨论】:

  • 如果您对汇编程序不够熟练,无法调用函数,那么您可能应该让编译器进行优化。您必须在汇编方面非常优秀且经验丰富,才能通过手动调优超越现代优化编译器。
  • 与编译器相比,我真的怀疑手动将 double 转换为 long int 会导致任何优化。这是一个如此简单的操作,它可能更可能导致更差的性能——因为编译器通常可以“查看”每条指令之外的内容。 (是需要的结果,存放在哪个寄存器中;放在xmm寄存器等会更好吗?)
  • @H2CO3:我会说,甚至可能是那个上帝。
  • @AkiSuihkonen,已知从 double 到 integer 的转换在留给编译器时是次优的,因为它无法做出任何简化假设。请参阅stackoverflow.com/questions/78619/…,尽管这可能已经过时:msdn.microsoft.com/en-us/library/z8dh4h17.aspx
  • 这可能是真的。还是例如gcc 4.6.3 允许自己做出一些假设并简单地写cvttsd2siq %xmm0, %rax(是的,不幸的是附近没有 x86 系统,只有 x64)

标签: c++ visual-studio-2005 x86 inline-assembly


【解决方案1】:

__asm fld input 实际上会尝试读取您的 pointer 值,就好像它是一个浮点值一样。如果要读取指针所指向的浮点值,则必须经过两步过程:将地址读入寄存器,然后使用寄存器中的地址读取数据.在 32 位平台上,它将类似于

__asm {
  mov eax, input
  fld qword ptr [eax]
  fistp output
}

我刚刚在 VS2005 中尝试过,它可以工作。 (请注意,正如其他人在 cmets 中所说,fist 不支持存储到 64 位 long long,而 fistp 支持。但您可能无论如何都需要 fistp,即弹出式存储。)

【讨论】:

  • 除非您要继续使用该值,否则您可能需要fistp 而不是fist
  • 有个小问题,它是 x86 架构,所以没有 rax 寄存器
  • fist 转换为 32 位整数,而不是 long long,不像 fistp(操作码 DF /7)。
  • @chill:MSVC++ 内联汇编器会根据接收变量的大小自动选择正确的操作码。所以这里fistfistp之间的选择只取决于OP是否要从FPU堆栈中弹出结果
  • @AndreyT:x86指令编码不一致——fist只支持16位和32位操作数,fistpfisttp支持16位、32位和64位
【解决方案2】:

最简单的可能是:

double input;
long long output;

__asm fld input
__asm fisttp output

这会进行“正常”的 double 到 long long 的转换,向零截断,就像 C 强制转换一样。但是,非常旧的(Pentium4 之前的)CPU 不支持fistpp,因此在此类机器上您需要使用fistp,它使用当前的舍入模式(通常舍入到最接近)。因此,如果你想例如向 -infinity 舍入,你需要保存当前的舍入模式,将其设置为你想要的,执行fistp 并恢复舍入模式:

double input;
long long output;
unsigned short oldcw, cw;

__asm fld input
__asm fstcw oldcw
cw = (oldcw & ~0xc00) | 0x400; // round towards -infinity
__asm fldcw cw
__asm fistp output
__asm fldcw oldcw

【讨论】:

    猜你喜欢
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2017-11-29
    • 2015-08-23
    • 2019-05-20
    • 2021-12-03
    相关资源
    最近更新 更多