2013-03-06 105 views
5

我有代碼調用了很多_ftol2_sse,有更快的選擇嗎?

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的,我想知道有沒有目前的方式來做到這一點。請注意,它表示最好的轉換是不會發生的,但我需要擁有它,所以這是不可能的。

回答

6

如果您針對的是通用x86硬件,那很難打敗它。運行時不確定目標機器是否具有SSE單元。如果是這樣,它可以執行x64編譯器的操作並嵌入cvttss2si操作碼。但是由於運行時必須檢查SSE單元是否可用,因此您將留下當前的實現。這就是ftol2_sse的實現。而且,如果SSE單元可用,它還會傳遞x87寄存器中的值,然後將其傳送到SSE寄存器。

您可以告訴x86編譯器針對具有SSE單元的機器。然後編譯器確實會發出一個簡單的cvttss2si內聯操作碼。這將會得到儘可能快的速度。但是如果你在舊機器上運行代碼,那麼它將會失敗。也許你可以提供兩個版本,一個用於SSE機器,另一個用於沒有SSE的機器。

這不會讓你獲得那麼多。這只是爲了避免ftol2_sse發生的所有開銷,而這些開銷在您實際完成工作的cvttss2si操作碼之前發生。

要從IDE更改編譯器設置,請使用項目>屬性>配置屬性> C/C++>代碼生成>啓用增強指令集。在命令行中,它是/ arch:SSE或/ arch:SSE2。

+0

完美,與x64代碼,這個工程快很多! – SinisterMJ 2013-03-06 15:09:53

1

對於double我不認爲你將能夠改善多少效果,但如果你有很多的float s到轉換,使用打包轉換可以幫助,以下是nasm代碼:

global _start 

section .data 
    align 16 
    fv1: dd 1.1, 2.5, 2.51, 3.6 

section .text 
    _start: 

    cvtps2dq xmm1, [fv1] ; Convert four 32-bit(single precision) floats to 32-bit(double word) integers and place the result in xmm1 

應該有內聯代碼,它允許您以更簡單的方式執行相同的操作,但我不熟悉使用內聯函數庫。雖然你沒有使用gcc,但是這篇文章Auto-vectorization with gcc 4.7讓人大開眼界,它讓編譯器生成良好的矢量化代碼變得非常困難。

1

如果您需要速度和大量目標機器的基礎,您最好引入所有算法的快速SSE版本以及通用算法 - 並選擇要在更高級別執行的算法。

這也意味着ABI也針對SSE進行了優化;並且可以在可用時矢量化計算,並且控制邏輯也針對體系結構進行了優化。

btw。即使FLD; FIST序列在Pentium上也不應該超過~7個時鐘週期。

+3

您需要更改舍入模式以獲得正確的截斷。就我所知,更改x87狀態字很慢。 – 2013-03-06 15:02:14

+0

@事實上的評論是準確的 – 2013-03-06 15:03:49

+0

好點。然後,不要更改狀態字_often_。 – 2013-03-06 17:44:52