_ftol2_sse,有更快的选择吗?

时间:2013-03-06 12:57:19

标签: c++ floating-point

我的代码调用了很多

int myNumber = (int)(floatNumber);

总共约占我CPU时间的10%(根据分析器)。虽然我可以放弃它,但我想知道是否有更快的选择,所以我试着四处寻找,偶然发现

  

http://devmaster.net/forums/topic/7804-fast-int-float-conversion-routines/   http://stereopsis.com/FPU.html

我尝试实现那里给出的Real2Int()函数,但它给了我错误的结果,并且运行速度较慢。现在我想知道,是否有更快的实现将double / float值置于整数,或者SSE2版本的速度是否达到最快?我找到的页面可以追溯到一点,所以它可能只是过时了,更新的STL更快。

目前的实施方式:

013B1030  call        _ftol2_sse (13B19A0h)

013B19A0  cmp         dword ptr [___sse2_available (13B3378h)],0  
013B19A7  je          _ftol2 (13B19D6h)  
013B19A9  push        ebp  
013B19AA  mov         ebp,esp  
013B19AC  sub         esp,8  
013B19AF  and         esp,0FFFFFFF8h  
013B19B2  fstp        qword ptr [esp]  
013B19B5  cvttsd2si   eax,mmword ptr [esp]  
013B19BA  leave  
013B19BB  ret  

我发现的相关问题:

  

Fast float to int conversion and floating point precision on ARM (iPhone 3GS/4)

     

What is the fastest way to convert float to int on x86

由于两者都是旧的,或者基于ARM,我想知道目前是否有这样的方法。请注意,它表示最佳转换是不会发生的转换,但我需要它,所以这是不可能的。

3 个答案:

答案 0 :(得分:6)

如果您的目标是通用x86硬件,那将很难被击败。运行时不确定目标机器是否具有SSE单元。如果是这样,它可以执行x64编译器所做的操作并内联cvttss2si操作码。但由于运行时必须检查SSE单元是否可用,因此您将获得当前的实现。这就是ftol2_sse的实现。而且,如果SSE单元可用,它会将x87寄存器中的值传递给SSE寄存器。

您可以告诉x86编译器定位具有SSE单元的计算机。然后编译器确实会发出一个简单的cvttss2si操作码内联。这将是你能得到的最快速度。但是如果你在旧机器上运行代码,那么它将失败。也许您可以提供两个版本,一个用于带SSE的机器,另一个用于没有SSE的机器。

这不会让你获得那么多。这只是为了避免在您实际到达执行工作的ftol2_sse操作码之前发生cvttss2si的所有开销。

要从IDE更改编译器设置,请使用Project>属性>配置属性> C / C ++>代码生成>启用增强指令集。在命令行上它是/ arch:SSE或/ arch:SSE2。

答案 1 :(得分:1)

对于double我不认为你能够很好地改进结果,但如果你有很多float转换使用打包转换可能会有所帮助,那么以下是{ {1}}代码:

nasm

应该有内在代码,允许你以更简单的方式做同样的事情,但我不熟悉使用内在库。虽然你没有使用gcc这篇文章Auto-vectorization with gcc 4.7让人们大开眼界,让编译器生成良好的矢量化代码是多么困难。

答案 2 :(得分:1)

如果您需要速度和大量目标机器,您最好为所有算法引入快速SSE版本,以及通用算法 - 并选择要在更高级别执行的算法。 / p>

这也意味着ABI也针对SSE进行了优化;并且您可以在可用时对计算进行矢量化,并且还针对体系结构优化控制逻辑。

顺便说一句。 Pentium上的偶数FLD; FIST序列不应超过~7个时钟周期。