【问题标题】:Converting inline ASM to intrinsic for x64 igraph将内联 ASM 转换为 x64 igraph 的内在
【发布时间】:2012-10-20 06:21:33
【问题描述】:

我正在从源代码编译适用于 x64 的 python 扩展 IGRAPH,而不是发行版中可用的 x86。我已经在 VS 2012 中整理了所有内容,当我在 src/math.c 中注释如下时它会编译

#ifndef HAVE_LOGBL
long double igraph_logbl(long double x) {
long double res;
/**#if defined(_MSC_VER)
  __asm { fld [x] }
  __asm { fxtract }
  __asm { fstp st }
  __asm { fistp [res] }
 #else
 __asm__ ("fxtract\n\t"
 "fstp  %%st" : "=t" (res) : "0" (x));
 #endif*/
    return res;
 }
#endif

问题是我不太了解 asm,也不太了解从 x86 到 x64 是否存在问题。据我所知,这是 4 个必须转换为 x64 内在函数的汇编指令的简短 sn-p。

有什么建议吗?走向内在是正确的方式吗?还是应该是子程序还是纯C?

编辑:如果有人想查看 igraph 扩展名的链接http://igraph.sourceforge.net/download.html

【问题讨论】:

  • fxtract 没有内在函数,因此该计划立即失败。如果您愿意转换非长双精度数,则可以使用 SSE2 内在函数轻松提取指数(顺便说一下,这将比 fxtract 快​​得多)。

标签: c++ c assembly visual-studio-2012 intrinsics


【解决方案1】:

在 x64 中,浮点通常使用 SSE2 指令执行,因为这些指令通常要快得多。您唯一的问题是 SSE 中没有等效的 fxtract 操作(这通常意味着 FPU 版本将作为复合指令实现,因此非常慢)。因此,在 x64 上实现为 C 函数可能会一样快。

我发现该函数有点难以阅读,但据我所知,它正在调用 fxtract,然后将整数值存储到 long double 指向的地址。这意味着 long double 将有一个“部分”未定义的值。尽我所能告诉上面的代码汇编不应该工作......但是自从我编写任何 x87 代码以来已经很长时间了,所以我可能只是生疏了。

无论如何,该功能似乎是logb 的实现,您不会在 MSVC 中找到它的实现。但是,它可以使用 frexp 函数实现如下:

long double igraph_logbl(long double x) 
{
    int exp = 0;
    frexpl( x, &exp );
    return (long double)exp;
 }

【讨论】:

  • 有趣。根据网络, frexp 仅在纯 C 中的 double 版本中,您必须去 cpp 才能获得 long double。我认为 igraph 在技术上都是 C 语言。
  • @WildaBeast:你从哪里得到这些信息?一个大问题是 SSE2 不再真的存在 long double (并不是说它真的存在......我的意思是.. long double 的大小是多少?)......无论如何它都会被转换为 double (至少在VS2012)。
猜你喜欢
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 2018-09-18
  • 1970-01-01
  • 2018-10-05
相关资源
最近更新 更多