2012-10-30 47 views
3

我正在从源代码编译python扩展IGRAPH for x64,而不是在发行版中可用的x86。我已经得到这一切在2012 VS整理出来,当我注释掉在SRC/math.c如下它编译将内联ASM转换为内联for x64 igraph

#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内在函数,从我所能看到的内容来看。

任何指针?内在是正确的方式?或者它应该是子程序还是纯C?

编辑:链接的igraph分机,如果有人想看到http://igraph.sourceforge.net/download.html

+0

“fxtract”没有内部函数,因此计划立即失败。如果你愿意切换你的非长双精度,你可以用SSE2内在函数很容易地提取指数(顺便说一下,它比'fxtract'快很多)。 – harold

回答

2

在64位浮点一般会使用SSE2指令被执行,因为这些一般都是速度快了很多。这里唯一的问题是没有等价于SSE中的fxtract op(通常意味着FPU版本将作为复合指令实现,因此非常慢)。因此,作为C函数的实现在x64上可能会更快。

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

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

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

有趣。根据网络,frexp在纯C版中只有双版本,你必须去cpp才能获得长双。 igraph在技术上全是C,我想。 – WildaBeast

+0

@WildaBeast:你从哪里得到这些信息?一个很大的问题是,SSE2不再存在长时间双倍存在(并不是说它真的存在......我的意思是什么尺寸是长双倍?)......它无论如何都会变成双倍(至少与VS2012)。 – Goz