MMX的数据结构 MMX指令集
源地址:http://dev.gameres.com/Program/Other/MMXData.htm
? ? ? ?http://www.360doc.com/content/12/1129/18/1317564_251021032.shtml
MMX的數據結構
? ? 多媒體軟件具有如下顯著的特點:
1、 小整型數據類型(圖形數據為8位 ,聲頻數據為16位)
2、 對小整型數據的頻繁且重復的計算操作(例如被頻繁調用的核心算法);
3、 許多操作具有內存的并行性(例如對大量的數據進行同一個加,減或乘法運算操作);
? ? MMX技術設計了一套基本的,通用的緊縮整形指令,共57條。
所謂“緊縮整形數據”是指多個8/16/32位的整形數據組合成為一個64位的數據.MMX指令主要就是使用
這種緊縮整形數據,它又分成4種整形類型:緊縮字節、緊縮字、緊縮雙字、緊縮4字
? ? *緊縮字節(Packed Byte): 8個字節組合成一個64位的數據;
? ? *緊縮字 (Packed Word): 4個字組合成一個64位的數據;
? ? *緊縮雙字(Packed Doubleword): 2個雙字組合成一個64位的數據;
? ? *緊縮4字 (Packed Quadword):一個64位數據
? ? 這樣一條MMX指令就能夠同時處理8/4/2個數據單元,這就是所謂的“單指令多數據SIMD”結構。這種結構
是MMX技術把機器性能提高的最根本因素。
? ? 為了方便使用64位緊縮整形數據,MMX技術含有8個64位的MMX寄存器(MM0-MM7),只有MMX指令可以使用MMX寄存器。值得一提的是,MMX寄存器是隨機存取的,但實際上是借用了8個浮點數據寄存器實現的。浮點處理單元FPU有8個浮點寄存器FPR,以堆棧方式存取。每個浮點數據寄存器有80位,高16位用于指數和符號,低64位用于有效數字。MMX利用其64位有效數字部分用做隨機存取的64位的MMX寄存器。也就是說MMX寄存器并非獨立寄存器,而是復用了fpu數據堆棧寄存器,也就是說使用mmx指令集會破壞fpu的計算,如果同時使用著兩種特性,一定要注意這點,避免出現莫名的錯誤。
MMX指令集
1、算術運算:
PADD[B、W、D] 環繞加[字節,字,雙字]
PADDS[B , W] 有符號飽和加[字節,字]
PADDUS[B , W] 無符號飽和加[字節,字]
PSUB[B、W、D] 環繞減[字節,字,雙字]
PSUBS[B,W] 有符號飽和減[字節,字]
PSUBUS[D,W] 無符號飽和減[字節,字]
PMULHW 緊縮字乘后取高位
PMULLW 緊縮字乘后取低位
PMADDWD 緊縮字乘,積相加
2、比較:
PCMPEQ[B,W,D] 緊縮比較是否相等[字節,字,雙字]
PCMPGT[B,W,D] 緊縮比較是否大于[字節,字,雙字]
3、類型轉換:
PACKUSWB 按無符號飽和壓縮[字成字節]
PACKSS[WB,DW] 按有符號飽和壓縮[字/雙字成/字節/字]
PUNPCKH[BW,WD,DQ] 擴展高位[字節,字,雙字成字,雙字,4字]
PUNPCKL[BW,WD,DQ] 擴展地位[字節,字,雙字成字,雙字,4字]
4、邏輯運算:
PAND 緊縮邏輯與
PANDN 緊縮邏輯與非
POR 緊縮邏輯或
PXOR 緊縮邏輯異或
5、位移:
PSLL[W,D,Q] 緊縮邏輯左移[字,雙字,4字]
PSRL[W,D,Q] 緊縮邏輯右移[字,雙字,4字]
PSRA[W,D] 緊縮算術右移[字,雙字]
7、數據傳送:
MOV[D,Q] 從MMX寄存器傳人/傳出[雙字/4字]
8、狀態清除
EMMS 清除MMX狀態
首先mmx指令集需要cpu的支持,但不是所有cpu都支持,不然也不會稱之為高級特性 了,所以在使用之前需要檢測,檢測指令為cpuid,獲得cpu的特性,cpuid雖然只有一條指令,但是其隱含的內容太多,這里僅僅介紹檢測SIMD指令集所需要的部分,其他一些信息可參閱Intel 手冊獲得。
當eax為1時,cpuid指令返回cpu簽名信息,放入ecx和edx寄存器中,相應位為1表示支持。檢測SIMD指令集的結果如下:
寄存器 位 特性
EDX ? ?? 23 支持MMX
EDX 25 支持SSE
EDX 26 支持SSE2
ECX 0 支持SSE3
具體檢測代碼如下(AT&T 語法):
.section .data
mmxstring: .asciz "支持mmx指令集\n"
ssestring: .asciz "支持sse指令集\n"
sse2string: .asciz "支持sse2指令集\n"
sse3string: .asciz "支持sse3指令集\n"
.section .text
.globl _main
_main:
movl $1, %eax
cpuid
mmxop:
test $0x800000, %edx
jz sseop
pushl $mmxstring
call _printf
sseop:
test $0x2000000, %edx
jz sse2op
pushl $ssestring
call _printf
sse2op:
test $0x4000000, %edx
jz sse3op
pushl $sse2string
call _printf
sse3op:
test $0x01, %ecx
jz end
pushl $sse3string
call _printf
end:
pushl $0
call _exit
? ? ??
? ? ? 下面正式開始mmx指令集的介紹,使用mmx需要三個步驟:
1、從整數值創建打包整數,載入mmx寄存器
2、使用mmx指令集計算
3、從mmx獲得結果,存入內存
? ? ? 第一個和最后一個步驟比較簡單,僅僅是數據移動而已,這里提到打包,因為這里要單指令多數據,所以需要把多數據合成一個操作數進行計算,存入64位的mmx寄存器中,打包的過程就是把 8個字節/4個字/2個雙字合成一個64位數據。
? ? ?從加減法說起,對于普通數據,如果數據溢出可以置標記位,但是對于多數據的運算,由于同時計算多個加法,就不能單純的設置標志,對mmx計算有幾種情況:
環繞運算 截斷其值,丟棄進位
帶符號飽和 最大/最小 帶符號值
無符號飽和 最大/最小 無符號值
? ? ? 其中飽和運算的預設值根據結果的位數決定,有符號8位最大為127,如果超過127,結果按127計算,其他情況與此類似,這里方便與一些圖形處理,比如色彩黑色為0,為無符號最小值,小于其值也按黑色處理。
? ? ? 好 了,到此可以看一下具體的指令,這里的指令有相同的格式,instruction source, destination;其中source可以是mmx寄存器或者64位內存,destination為mmx寄存器。這是AT&T語法,對于 MASM語法源目的操作數相反。
? ?指令 說明
paddb 環繞打包字節整數加法
paddw 環繞打包字整數加法
paddd 環繞打包雙字整數加法
paddsb 帶符號飽和打包字節整數加法
paddsw 帶符號飽和打包字整數加法
paddusb ?? 無符號飽和打包字節整數加法
paddusw 無符號飽和打包字整數加法
psubb 環繞打包字節整數減法
psubw 環繞打包字整數減法
psubd 環繞打包雙字整數減法
psubsb ? ? 帶符號飽和打包字節整數減法
psubsw ?? 帶符號飽和打包字整數減法
psubusb 無符號飽和打包字節整數減法
psubusw 無符號飽和打包字整數減法
下面以AT&T加法為例進行說明,這里以飽和方式計算4個無符號字之和:
# add four word
# output : result is 18932, 7631, 65535, 510
.section .data
value1: .short 12300, 2384, 60000, 456
value2: .short 6632, 5247, 40000, 54
outstring: .asciz "result is %u, %u, %u, %u\n"
.section .text
.globl _main
_main:
movq value1, %mm0
movq value2, %mm1
paddusw %mm1, %mm0
movq %mm0, value1
movl $value1, %ebx
xorl %eax, %eax
movw 6(%ebx), %ax
pushl %eax
movw 4(%ebx), %ax
pushl %eax
movw 2(%ebx), %ax
pushl %eax
movw (%ebx), %ax
pushl %eax
pushl $outstring
call _printf
pushl $0
call _exit
? ? ? movq 指令把內存中的數據傳送至mmx寄存器,如果數據之前在內存中不是連續的,則需要集中存放,即進行打包,之后使用paddusw進行加法計算,輸出時 word需轉化成dword放入堆棧,可以看到以飽和方式第三個結果為65535,即16位無符號數的最大值。從這里例子可以看出,通過一條指令計算了四 個word整數相加,很大程度上提高了計算的效率,但是同時需要注意,整數的打包以及傳送過程也需要耗時,如果打包操作很多,結果不是提高效率而是降低效率了。
? ? ?mmx指令集的加法根據需要有飽和方式和環繞方式計算,但對于乘法而言,由于結果的寬度可能是操作數的兩倍,所以兩種方式看上去都不合適,所以intel提供了兩個指令,一個得到計算結果的低字節,另一個得到計算結果的高字節。
? ? 指令 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?描述
pmulluw ? ? ? ??對無符號16位整數相乘取結果低16位
pmulhuw 對無符號16位整數相乘取結果高16位
pmullw ? ? ? ? ?對有符號16位整數相乘取結果低16位
pmulhw ? ? ? ??對有符號16位整數相乘取結果高16位
pmaddwd 對4個帶符號整數相乘,高位兩個結果相加存入高32位,低位相同
? ? ? mmx 指令集還提供對四字值進行布爾邏輯操作和移位指令:
? 指令 ? ? ? ? ? ? ? ? ? ? ?描述
pand 對源和目標操作數按位與操作
pandn 對目標操作數進行按位邏輯非操作,然后對源和目標操作數按位與操作
por ? ? ? ? ? 對源和目標操作數按位或操作
pxor ? ? ? ??對源和目標操作數按位異或操作
psll ? ? ? ? ?對目標操作數執行邏輯左移操作,使用0填充空位
psra 對目標操作數執行邏輯右移操作,使用0填充空位
其AT&T指令格式如下:
pand source, destination
其中source是mmx寄存器或者64位內存,destination必須是mmx寄存器。移位指令可以使用字,雙字或者四字操作數,還有移位的位置數量。MASM格式的源目的操作數相反。
mmx構架提供了用于比較兩個值的指令:
? ? ?指令 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?描述
pcmpeqb 比較打包字節整數值的相等性
pcmpeqw 比較打包字整數值的相等性
pcmpeqd 比較打包雙字整數值的相等性
pcmpgtb 判斷打包字節整數值是否大于另一個
pcmpgtw 判斷打包字整數值是否大于另一個
pcmpgtd 判斷打包雙字整數值是否大于另一個
? ? 因為mmx同時比較多個數據,所以不能設置標志,替換的做法是把判斷結果放到目標打包整數值中,如果打包整數值滿足對比提交,就把結果設置為全1,否則設置為全0。
? ? 由于mmx指令集并非所有cpu都可以支持,所以對c語言這種編譯通用性的程序而言,是不會貿然使用mmx指令集的,這也對我們手工匯編優化程序提供了很大的空間,但是需要注意打包整數的效率損耗。
總結
以上是生活随笔為你收集整理的MMX的数据结构 MMX指令集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV算法加速(2)使用SIMD指
- 下一篇: Intel汇编-传送MMX整数