SSE指令集(1)-基礎(chǔ)篇

最近根據(jù)開(kāi)發(fā)任務(wù)安排了對(duì)C++的代碼用SSE指令優(yōu)化的計(jì)劃,自己在這方面完全是新手,所以只能從0開(kāi)始,一步步學(xué)習(xí)。特此記錄自己學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。
SSE(Stream SIMD Extensions)是Intel在其計(jì)算機(jī)芯片Pentium3中引入的指令集,是繼MMX的擴(kuò)充指令集。提供了70條新指令。
SIMD,single instruction multiple data,單指令流多數(shù)據(jù)流,一次運(yùn)算指令可以執(zhí)行多個(gè)數(shù)據(jù)流,可以提高程序的運(yùn)算速度,是實(shí)現(xiàn)DLP(Data Level Parallelism)的關(guān)鍵。

SSE本質(zhì)上類似于一個(gè)向量處理器,包括了4個(gè)主要部分:?jiǎn)尉_度浮點(diǎn)數(shù)運(yùn)算指令、整數(shù)運(yùn)算指令(為MMX的延伸,并與MMX使用同樣的暫存器)、Cache控制指令、狀態(tài)控制指令。

SSE浮點(diǎn)運(yùn)算指令分為兩大類:packed和scalar
packed指令是一次對(duì)XMM暫存器中的四個(gè)浮點(diǎn)數(shù)(DATA0~DATA3)均進(jìn)行計(jì)算,而scalar只對(duì)XMM暫存器中的DATA0進(jìn)行計(jì)算,見(jiàn)下圖。

0_1322138417SGI3.gif.png

SSE指令的一般格式由三部分組成,第一部分表示指令的作用,第二部分是s或者p分別表示scalar或packed,第三部分為s,表示單精度浮點(diǎn)數(shù)(single precision floating point data)


0_1322142131Tc8T.gif.png

SSE定址/尋址方式:
SSE指令和一般的x86指令很類似,基本包括兩種定址方式:寄存器-寄存器方式(reg-reg)和寄存器-內(nèi)存方式(reg-mem):
addps xmm0,xmm1;reg-reg
addps xmm0,[ebx]; reg-mem

SSE指令表

浮點(diǎn)指令

  • 記憶體到暫存器/暫存器到記憶體/暫存器之間的資料搬移
    純量(scalar):MOVSS
    包裹式(packed):MOVAPS,MOVUPS,MOVLPS,MOVHPS,MOVLHPS,MOVHLPS

  • 數(shù)學(xué)運(yùn)算
    純量:ADDSS,SUBSS,MULSS,DIVSS,RCPSS,SQRTSS,MAXSS,MINSS,RSQRTSS
    包裹式:ADDPS,SUBPS,MULPS,DIVPS,RCPPS,SQRTPS,MAXPS,MINPS,RSQRTPS

  • 比較
    純量:CMPSS,COMISS,UCOMISS
    包裹式:CMPPS

  • 資料拆包(unpack)與隨機(jī)搬移(shuffle)
    包裹式:SHUFPS,UNPCKHPS,UNPCKLPS

  • 資料形態(tài)轉(zhuǎn)換
    純量:CVTSI2SS,CVTSS2SI,CVTTSS2SI
    包裹式:CVTPI2PS,CVTPS2PI,CVTTPS2PI

  • 逐位邏輯運(yùn)算
    包裹式:ANDPS,ORPS,XORPS,ANDNPS

整數(shù)指令

  • 數(shù)學(xué)運(yùn)算
    PMULHUW,PSADBW,PAVGB,PAVGW,PMAXUB,PMINUB,PMAXSW,PMINSW
  • 資料搬移
    PEXTRW,PINSRW
  • 其它
    PMOVMSKB,PSHUFW

其它指令

  • MXCSR管理
    LDMXCSR,STMXCSR
  • 快取與記憶體管理(SSE除了運(yùn)算的指令外,還支持了cache控制指令)
    MOVNTQ,MOVNTPS,MASKMOVQ,PREFETCH0,PREFETCH0,PREFETCH1,PREFECTCH2,PREFETCHNTA,SFENCE
    prefetch指令的主要目的,是提前讓CPU載入稍后運(yùn)算所需要的數(shù)據(jù)。通常是在對(duì)目前的資料進(jìn)行與運(yùn)算之前,告訴CPU載入下一批數(shù)據(jù)。這樣就可以讓目前的運(yùn)算和載入下一批數(shù)據(jù)的動(dòng)作可以同時(shí)進(jìn)行。不同prefetch指令則是告訴CPU將數(shù)據(jù)載入不同層次的cache。prefetch指令不會(huì)產(chǎn)生任何exception。

除了prefetch之外,另一個(gè)指令是movntps,它的intrinsics是 _mm_stream_ps。這個(gè)指令的用途,是要求 CPU 在寫(xiě)入數(shù)據(jù)的時(shí)候,不要把數(shù)據(jù)寫(xiě)到 cache 中,而是直接將數(shù)據(jù)寫(xiě)到主記憶體中。實(shí)際上它以 write combining 的方式寫(xiě)入的。為什麼要這樣做呢?這是因?yàn)?,很多時(shí)候計(jì)算的結(jié)果并不是立刻需要用到的,通常是很久以后才會(huì)用到。所以,這些數(shù)據(jù)如果被放在 cache 中,完全是浪費(fèi)空間。而且,更糟的是,它們可能會(huì)把 cache 中有用的數(shù)據(jù)擠掉,而使得這些數(shù)據(jù)常常需要重新從主記憶體中載入。因此,如果讓這些數(shù)據(jù)不要被放在 cache 中,就可以避免這種問(wèn)題。

參考閱讀:
http://dev.gameres.com/Program/Other/SSEjianjie.htm http://blog.csdn.net/gengshenghong/article/details/7008704
http://www.cnblogs.com/clover-toeic/p/3853132.html (對(duì)字節(jié)對(duì)齊不清的童鞋可以參考這篇文章)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容