close

from 
作者:Alex Farber
出處:http://www.codeproject.com/cpp/sseintro.asphttp://blog.csdn.net/showlong/archive/2010/02/11/5306989.aspx
出處:http://blog.csdn.net/showlong/archive/2010/02/11/5306989.aspx

 

SSE技術簡介


Intel公司的單指令多資料流式擴展(SSE,Streaming SIMDExtensions)技術能夠有效增強CPU浮點運算的能力。Visual Studio .NET2003提供了對SSE指令集的程式化支持,從而允許使用者在C++代碼中不用編寫匯編代碼就可直接使用SSE指令的功能。MSDN中有關SSE技術的主題[1]有可能會使不熟悉使用SSE匯編指令程式化的初學者感到困惑,但是在閱讀MSDN有關文檔的同時,參考一下Intel軟體說明書(Intel Software manuals)[2]會使你更清楚地理解使用SSE指令程式化的要點。 


參考文檔:
[1]MSDN, SSE技術主題:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vcrefstreamingsimdextensions.asp
[2]Intel軟體說明書(Intel Software manuals):
http://developer.intel.com/design/archives/processors/mmx/index.htm 




SIMD(single-instruction, multiple-data)是一種使用單道指令處理多道資料流的CPU執行模式,即在一個CPU指令執行周期內用一道指令完成處理多個資料的操作。考慮一下下面這個任務:計算一個很長的浮點型數組中每一個元素的平方根。

實現這個任務的算法可以這樣寫:



for each   f in array         //對數組中的每一個元素
     f = sqrt(f)              //計算它的平方根


為了了解實現的細節,我們把上面的代碼這樣寫:


for each   f in array
{
     把f從記憶體加載到浮點寄存器
     計算平方根
     再把計算結果從寄存器中取出放入記憶體
}


具有IntelSSE指令集支持的處理器有8個128位的寄存器,每一個寄存器可以存放4個(32位)單精度的浮點數。SSE同時提供了一個指令集,其中的指令可以允許把浮點數加載到這些128位的寄存器之中,這些數就可以在這些寄存器中進行算術邏輯運算,然后把結果放回記憶體。採用SSE技術后,算法可以寫成下面的樣子:


for each   4 members in array   //對數組中的每4個元素
{
     把數組中的這4個數加載到一個128位的SSE寄存器中
     在一個CPU指令執行周期中完成計算這4個數的平方根的操作
     把所得的4個結果取出寫入記憶體
}


C++程式化人員在使用SSE指令函數程式化時不必關心這些128位的寄存器,你可以使用128位的資料類型“__m128”和一系列C++函數來實現這些算術和邏輯操作,而決定程序使用哪個SSE寄存器以及代碼優化是C++編譯器的任務。當需要對很長的浮點數數組中的元素進行處理的時候,SSE技術確實是一種很高效的方法。


SSE程序設計詳細介紹


包含的頭文件:
所有的SSE指令函數和__m128資料類型都在xmmintrin.h文件中定義:#include
在xmmintrin.h頭文件里包含一些函數:主要有加、減、剩、除、開方、倒數、最大最小等等算術函數,與、或、非等邏輯函數,以及各種比較函數和轉換函數,具體請看看該頭文件。因為程序中用到的SSE處理器指令是由編譯器決定,所以它並沒有相關的.lib庫文件。目前市面上的大多數CPU(Intel、AMD)均支持SSE指令集,在開發環境中,VS2002及以上才支持SSE指令函數庫。


資料分組(Data Alignment
由SSE指令處理的每一個浮點數數組必須把其中需要處理的數每16個位元組(128位二進制)分為一組。


靜態數組(static array)可由__declspec(align(16))關鍵字聲明:
__declspec(align(16)) float m_fArray[ARRAY_SIZE];


動態數組(dynamic array)可由_aligned_malloc函數為其分配空間:
m_fArray = (float*) _aligned_malloc(ARRAY_SIZE * sizeof(float), 16);
由_aligned_malloc函數分配空間的動態數組可以由_aligned_free函數釋放其占用的空間:_aligned_free(m_fArray);


__m128 資料類型
該資料類型的變量可用做SSE指令的操作數,它們不能被使用者指令直接存取。_m128類型的變量被自動分配為16個位元組的字長。


CPU對SSE指令集的支持
如果你的CPU能夠具有了SSE指令集,你就可以使用Visual Studio .NET2003提供的對SSE指令集支持的C++函數庫了,你可以查看MSDN中的一個Visual C++CPUID的例子[4],它可以幫你檢測你的CPU是否支持SSE、MMX指令集或其它的CPU功能。


參考文檔:
[4] Microsoft Visual C++ CPUID示例:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample/html/vcsamcpuiddeterminecpucapabilities.asp
arrow
arrow
    全站熱搜

    chunyuan 發表在 痞客邦 留言(6) 人氣()