MMX開發文件 (轉)
MMX開發文件:namespace prefix = o ns = "urn:schemas--com::office" />
I MMX簡介
的MMX™技術是對Intel體系結構(IA)指令集的擴充套件。該技術使用了單指令多資料技術(SIMD)技術,以並行方式處理多個資料元素,從而提高了多和通訊的執行速度。MMX™指令集增加了57條新的操作碼和一個新的64位四字資料型別。
MMX™技術提高了很多應用的,例如活動影像、視訊會議、二維圖形和三維圖形。幾乎每一個具有重複性和順序性整數計算的應用程式都可以從MMX™技術中受益。對於8位、16位和32位資料元素的處理,改善了程式的效能。一個MMX™指令可一次操作8個位元組,且在一個時鐘週期內完成兩條指令,也就是說,可在一個時鐘週期內處理16個資料元素。另外,為增強效能,MMX™技術為其它功能釋放了額外的週期。以前需要其它支援的應用程式,現在僅需軟體就能執行。更小的處理器佔用率給更高程度的併發技術提供了條件,在當今眾多的操作中這些併發技術得到了利用。在基於Intel的分析系統中,某些功能的效能提高了50%到400%。這種數量級的效能擴充套件可以在新一代處理器中得到體現。在軟體核心中,其速度得到更大的提高,其幅度為原有速度的三至五倍。
MMX的缺點:由於MMX的運算指令必須在資料配對整齊的時候才能使用,所以使用MMX指令要比普通的指令多餘許多分組配對的指令,如果運算不是特別的整齊的話,就要浪費大量的時間在資料的配對上,所以說MMX指令也不是萬能的,也有其很大的缺陷。同時MMX指令在處理16位資料的時候才能發揮最大的作用,處理8位資料要有一點技巧。而處理32位資料,MMX指令幾乎沒有什麼加速能力。(考慮分組耗時的話)
II MMX基本指令集
具體細節請參閱《INTEL 體系結構MMX技術程式設計師參考手冊》第五章
2.1 複製指令
movq:64位資料複製,如果8位對齊的話,是一個64位寫,否則2個32位寫。
movd:32位資料複製,注意:如果從記憶體向MMX暫存器複製,MMX高32位清零!
2.2 分組指令
分組指令是MMX特有的,所以對於它我們要特別的關注。分組指令基本上可以分為2類,一類是不帶符號緊縮的,一類是帶符號緊縮的。現在我們分別予以介紹:
①punpcklbw / punpcklwd / punpckldq (l表示低位分組,bw8位,wd16位,dq32位):它是簡單的將兩個MMX暫存器的低32位交錯組合為一個64位資料。所以它是不能將長資料轉換為短資料的。
②packuswb 將16位資料轉換為無符號的8位資料。所以可以將兩個MMX暫存器不交錯的合為一個64位資料。
③packsswb/packssdw 將32位-》16位,16位-》8位,都是有符號的資料。
2.3 運算指令
加法運算指令:pad(w)(d):沒有越界保護的加法,當越界的時候僅僅丟棄超出範圍的高位位元,(b)(w)(d)分別為8,16,32位加法;paddsb(w):具有越界保護的有符號加法,當上溢的時候為0x7fff,下溢的時候為0x8000;padd(w):具有越界保護的無符號加法,當上溢的時候為0x7fff,下溢的時候為0x0。
減法運算指令同上;add改為sub。
乘法指令:pmullw / pmulhw 是4個16位資料的乘法,pmullw中是結果的低16位,pmulhw是結果的高16位。pmaddwd 乘加指令。
2.4 邏輯指令,移位指令和EMMS指令
細節參見《INTEL 體系結構MMX技術程式設計師參考手冊》。
III MMX經典處理策略
①資料輸入輸出:
在輸入資料的時候,經典的處理方法是將一個陣列整個“Load”到MMX暫存器中。這樣簡單同時利用了MMX64位讀寫資料的能力,提高了效能。同樣在輸出的時候,也是將一個64位MMX暫存器中的資料內容整個“Store”到記憶體中。
如果實在是不能這樣處理的話,就要利用移位指令了。比如說將一個MMX內的4個16位資料分別複製到不同的記憶體變數(或者16位通用暫存器中)x1,x2,x3,x4,那麼可以這樣處理:
movd eax,mm1
psrlq mm1,32
movd ebx,mm1
mov x1,ax
mov x2,bx
shr eax,16
shr ebx,16
mov x3,ax
mov x4,bx
可見如果不採用陣列形式的話,輸入輸出將十分的麻煩。
②資料分組以及求絕對值的方法等:
細節請參閱《INTEL 體系結構MMX™ 技術開發者手冊》第五章
IV 自定義組合指令
①八位無符號數的移位:
在MMX指令集中是沒有8位資料的移位指令的,但是有的時候我們確實需要,所以可以用以下兩個指令來實現:
psrlq mm0,1
pand mm0,0x7f7f7f7f7f7f7f7f
②如何防止計算過程中越界:
比如在計算的時候,我們有(x1+x2+1)>>1,這個時候x1+x2就會越界(8位資料),那麼我們就不得不使用替代了辦法,比如(x1>>1+x2>>1)這個處理是不精確的,在不需要很精確的場合,是可以使用的,但是如果結果差錯1都不可容忍的話,就要進行一點處理:
pand mm0,0x01010101010101 //保留資料的最後一位數
pand mm1,0x01010101010101 //保留資料的最後一位數
por mm0,mm1
paddusb mmx,mm0 //修正資料
(x1>>2+x2>>2):這個處理是通用的
pand mm0,0x03030303030303 //保留資料的最後兩位數
pand mm1, 0x03030303030303 //保留資料的最後兩位數
paddusb mm0,mm1
psrlq mm0,2
pand mm0,0x3f3f3f3f3f3f3f3f
paddusb mmx,mm0
③符號擴充套件指令:
mm0:*,*,A,B => 現在要符號擴充套件為 mm0:(A符號)A, (A符號)B
movq mm1,mm0
pcgtm mm1,0 //比較mm0,生成mm1:(A符號) (B符號)()()
punpcklwd mm0,mm1
④分組指令
除了基本的分組指令以外,我們還可以利用移位指令和pand por指令來實現分組的功能,移位主要是要產生0,這樣por mm0,mm1就可以將mm0和mm1合併了。
比如:mm0(*,*,A,B) mm1(0,0,C,D) 則
psllq mm0,32
por mm0,mm1 => (A,B,C,D) 當然這個例子我們可以用普通的分組指令實現,但是在某些複雜的處理中,這樣的處理是必須的。
總之,要靈活運用MMX的現有指令來實現自己需要的功能。
V MMX心得
使用MMX技術進行程式設計,目的就是要提高運算速度,所以,對於如何儘可能的提高程式碼的,我們是要特別關注的。這裡,我介紹一些需要注意的事項。
① 儘可能的提高記憶體訪問的容量,我們可以看看下面的程式碼:
for (j=0; j { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3]; d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7]; d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11]; d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15]; s+= lx2; d+= lx; } __asm{ pushf mov edx,d ptr h xor ecx,ecx mov esi,dword ptr s mov edi,dword ptr d mov eax,lx2 mov ebx,lx AGAIN: movq mm0,byte ptr [esi] movq mm1,byte ptr [esi+8] movq byte ptr [edi],mm0 movq byte ptr [edi+8],mm1 add esi,eax add edi,ebx add ecx,1 cmp ecx,edx jl AGAIN emms popf } 僅僅將幾個8位的寫,改為64位的寫,測試得到速度提升了25%,同樣的道理,我們要儘可能的將幾個movq寫在一起,這樣可以提高5%左右的速度。原C程式碼的效率也是很高的,它不用陣列的【】【】來定址,而是將s+= lx2; 從而將二維陣列的定址改為一維陣列的定址。儘可能的減少定址的複雜度,這也是一種高效的辦法。 還有一點就是如果將原來的簡單賦值改為memcpy()的話,可以提高大約10%的速度。這也是提高了資料流通容量的關係。 ② 一些要注意的地方: 1. 儘可能的使用static變數, 訪問這樣的變數是很快的=訪問立即數的速度 2. 由於只有一個mmx移位暫存器, (移位分組指令) 是不能配對的 3. 不要在eax使用完, 使用ax, 不要使用完一個mm1,就立即使用它 4. 可以這樣立即使用mm1, movq mm2,mm1 movq mm1,mm3 (Z順序是可以的) 5. (4個以上)movq儘可能的在一起, 前提是在一起的mov不要使用一樣的mmx暫存器 6. mov eax, [esi] ([esi+2*eax]) 訪問定址的記憶體是特別的慢的 7. 同上 stow 也是很慢的 (mov cx,n; l是很慢的,如果可能,要展開迴圈) 8. 儘可能的在暫存器中完成操作,不要去訪問記憶體 9. 用變數名訪問變數,尤其是static的,是很快. 10. 訪問定址的記憶體的速度下降 》 資料不對齊8位的速度下降 》 指令不配對的速度下降 11. 所以在傳統的程式碼的方法中,構造陣列,然後將運算變為查表的方法,有的時候在MMX技術內反而會降低速度。(這個時候,如果真的用查表有提升速度的話,建議採用段地址+偏移量的辦法)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992338/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MyScript 開發文件
- 商城式開發文件
- vue3開發文件Vue
- [開發文件]bootstrap中文手冊boot
- PHP蜘蛛爬蟲開發文件PHP爬蟲
- 介面開發文件及注意事項
- 微信支付開發文件連結
- [轉] composer – 文件 – 命令列命令列
- C# 將PDF文件轉換為Markdown文件C#
- 開發框架文件體系化的思考框架
- ModStart開發者文件-系統架構架構
- 敏捷開發,如何編寫架構文件敏捷架構
- [譯] 如何閱讀蘋果開發文件蘋果
- excel表格怎麼轉換成word文件 表格資料轉換到文件Excel
- Python 將Word/ Exce/ PDF/ PPT文件轉為OFD文件Python
- IBM 開源的文件轉化利器「GitHub 熱點速覽」IBMGithub
- pdf轉換成word文件
- Mqtt 學習文件【轉載】MQQT
- OpenHarmony開發者文件開源計劃,快快加入吧
- 玩轉iOS開發《建立CocoaPods開發庫》iOS
- 軟體開發專案文件系列之一文件綜述
- OpenHarmony 官網文件有哪些上新?下篇:裝置開發文件上新
- OpenHarmony 官網文件有哪些上新?上篇:應用開發文件上新
- Facebook 遊戲開發更新文件 API 參考文件 v5.0遊戲開發API
- Facebook 遊戲開發更新文件 API 參考文件 v6.0遊戲開發API
- 2022最新IntellJ IDEA的zheng開發部署文件IntelIdea
- 敏捷開發與文件:互補還是互斥?敏捷
- 2022最新IntellJ IDEA諾依開發部署文件IntelIdea
- 2022最新IntellJ IDEA的mall開發部署文件IntelIdea
- 車票100–火車票介面開發文件
- Facebook 小遊戲開發更新文件 API 參考文件 v6.0遊戲開發API
- 轉換不同文件到pdf
- 利用powershell轉wps文件到pdf
- Ocelot中文文件-轉換ClaimsAI
- Ocelot中文文件-轉換HeadersHeader
- Java開發者的Python快速實戰指南:實用工具之PDF轉DOCX文件(視覺化介面)JavaPython視覺化
- OCR文件識別:圖片快速轉換成電子文件
- IOS技術分享| iOS快速生成開發文件(一)iOS
- IOS技術分享| iOS快速生成開發文件(二)iOS