內部 API

使用 MMX™ 技術內部函式以及“數據流單指令多數據擴充套件指令集”與“第二代數據流單指令多數據擴充套件指令集”內部函式進行編碼的好處是,可以使用 C 函式呼叫與 C 變數的語法替代硬體暫存器。這使得您不再需要管理暫存器與編寫彙編程式。而且編譯器還優化指令排程,從而使可執行檔案執行速度更快。對於新指令集中的每個計算型與數據操作指令,都有一個對應的 C 內部函式直接去實現它。內部函式可供指定演算法的底層實現(指令選擇),而將指令排程與暫存器分配交給編譯器去完成。

MMX™ 技術內部函式

MMX 技術內部函式基於新的 __m64 數據型別,以代表 MMX 技術暫存器的特定內容。您可以按照位元組、短整數、32 位值或 64 位對象的形式指定值。不過,__m64 數據型別並非 ANSI C 基本數據型別,因此必須遵循以下使用限制:

數據流單指令多數據擴充套件指令集與第二代數據流單指令多數據擴充套件指令集內部函式

所有的“數據流單指令多數據擴充套件指令集”與“第二代數據流單指令多數據擴充套件指令集”內部函式都會利用到奔騰(R) III 與奔騰 4 處理器的 xmm 暫存器。這些內部函式支援三種數據型別:__m128、__m128d 及 __m128i。

編譯器將 __m128、__m128d 及 __m128 區域性與全域性數據對齊堆疊的 16 位元組邊界。要對齊整數、浮點或雙精度陣列,可以使用 declspec 語句,具體介紹詳見“英特爾(R) C++ 編譯器(含第二代數據流單指令多數據擴充套件指令集支援)使用者指南”(訂購編號 718195-2001)。

__m128 數據型別並非 ANSI C 基本數據型別,因此它的使用有以下限制:

__m128、__m128d 及 __m128i 只能在賦值語句的左側作為返回值或參數使用。不要在其它算術表達式(如 "+" 與 ">>")中使用它。不要使用常值初始化 __m128、__m128d 及 __m128i;沒有辦法表示 128 位常數。在聚集中使用 __m128、__m128d 及 __m128i 對象,如聯合(例如,要訪問浮點元素)與結構。可以取這些對象的地址。僅在本使用者指南介紹的內部函式中使用 __m128、__m128d 及 __m128i 數據。

編譯器將 __m128、__m128d 及 __m128i 區域性數據對齊堆疊的 16 位元組邊界。全域性 __m128 數據也在 16 位元組邊界上對齊。(要對齊浮點陣列,可以使用下節介紹的對齊 declspec)。不管使用壓縮還是標量數據,新指令集都按照相同的方式對待 SIMD 浮點暫存器,因此沒有 __m32 數據型別可以代表您可能需要的標量數據。對於標量操作,應該使用 __m128 對象與內部函式的“標量”形式;編譯器與處理器使用 32 位記憶體引用實現這些操作。

後綴 ps 與 ss 用於代表“壓縮單精度”與“標量單精度”操作。壓縮浮點值按從右到左的順序表示,最低位的字(最右側)用於標量操作:[z, y, x, w]。要理解記憶體儲存如何反映這點,請參閱下例。

操作

float a[4] { 1.0, 2.0, 3.0, 4.0 };
__m128 t _mm_load_ps(a);

產生的結果跟以下語句的相同:

__m128 t _mm_set_ps(4.0, 3.0, 2.0, 1.0);

也就是說,

t [ 4.0, 3.0, 2.0, 1.0 ]

其中“標量”元素是 1.0。

有些內部函式因為需要多條指令來實現,因此可稱作是“複合的”。使用內部函式編寫程式時,應該去熟悉“數據流單指令多數據擴充套件指令集”、“第二代數據流單指令多數據擴充套件指令集”以及 MMX 技術提供的硬體功能。

記住以下三個要點:

特定的內部函式(如 _mm_loadr_ps 與 _mm_cmpgt_ss)不受指令集直接支援。儘管這些內部函式是非常方便的程式設計輔助手段,但還是要注意它們的實現成本。作為 __m128 對像載入或儲存的數據通常是按照 16 位元組對齊。由於指令的性質,有些內部函式要求它們的參數必須是立即數,也就是說是整型常數(常值)。作用於兩個 NaN(非數值)參數的算術運算的結果未定義。因此,使用 NaN 參數的浮點操作產生的行為可能與對應的彙編指令的預期行為有所不同。

如需有關每個內部函式的詳細說明及其用法的附加資訊,請參閱 Intel C++ Compiler User's Guide With Support for the Streaming SIMD Extensions 2【英特爾 C++ 編譯器(含第二代數據流單指令多數據擴充套件指令集支援)使用者指南,訂購編號 718195-2001】。