intel的mmx技術是對intel體系結構(ia)指令集的擴充套件。該技術使用了單指令多資料技術(simd)技術,以並行方式處理多個資料元素。mmx指令集增加了57條新的操作碼和乙個新的64位四字資料型別,增加了八個新的64位mmx暫存器,每個暫存器可按名稱mm0-mm7直接訪問。這意味著我們可以在乙個暫存器裡最多存8個資料(最小單位位元組)。
sse系列是mmx的超集,直到sse2才跟mmx有本質的區別,新增了對64位雙精度浮點數的支援,以及對整型資料的支援,也就是說這個指令集中所有的mmx指令都是多餘的了,同時也避免了占用浮點數暫存器。這個指令集還增加了對cpu的快取的控制指令。新的sse暫存器命名為xmm0~xmm7,每個128位。
對h264的優化主要用到了mmx和sse2。舉個例子,在h264解碼端的idct和quant裡,要操作的數是乙個4x4的矩陣,很適合拿來優化。 idct計算公式:
其中,「ei
」已在前面的反量化中完成,其結果為
wr,所以這裡只進行以下運算:
在反變換過程中,可以分成兩次一維變換,使用了蝶形演算法來簡化運算。 原函式就不給了,直接看優化完成後的優化**:
memcpy(&m7,(&img->cof[i0][j0][0][0]),sizeof(short)*16);
//如果不能採用陣列形式的話,輸入輸出將十分的麻煩。只能通過移位指令,浪費大量的時間。
_mm_prefetch(&m7,_mm_hint_nta);
// _mm_prefetch將資料預存到cache裡,一次存乙個cache line的資料,_mm_hint_nta表示存到離cpu最近的cache裡(既l1 cache)。在操作開始前執行_mm_prefetch可以避免由於讀未命中產生的大量延時。
_asm
畫素恢復操作:
img->m7[i][j] =max(0,min(img->max_imgpel_value,( img->m7[i][j] +((long)img->mpr[i+ioff][j+joff] <<6)+32)>>6));
img->m7[i][j1]=max(0,min(img->max_imgpel_value,( img->m7[i][j1]+((long)img->mpr[i+ioff][j1+joff]<<6)+32)>>6));
mmx裡沒有max和min相關的指令操作,因此用sse2進行優化。intel提供了intrinsics庫讓我們寫sse**更方便快速,但是這樣會比彙編**要慢,因為它不在乎暫存器的分配和重新使用。
舉個例子:
temp_m70_sse=_mm_slli_epi16(temp_m70_sse,6);
_asm
temp_m70_sse=_mm_add_epi16(temp_m70_sse,temp_32_sse);
_asm
可以看到,運用這些指令的時候,每條指令都被單獨的處理,沒有考慮前後相關性,導致資料多次進行訪問,降低了速度,有可能比原來的c語言更慢。 剩下沒什麼好說的,優化後的**如下:
temp_32_sse=_mm_set1_epi16(32);
m70_sse=_mm_set_epi16(i16a[13],i16a[9],i16a[5],i16a[1],i16a[12],i16a[8],i16a[4],i16a[0]); //由於要處理的資料在記憶體上不是連續的,因此把這些資料讀到xmm暫存器裡會耗費大量時間,編譯後看反彙編的的**就知道了。 m71_sse=_mm_set_epi16(i16a[15],i16a[11],i16a[7],i16a[3],i16a[14],i16a[10],i16a[6],i16a[2]); temp_255_sse=_mm_set1_epi16(img->max_imgpel_value); temp_zero_sse=_mm_set1_epi16(0); temp_m70_sse=_mm_set_epi16(img->mpr[i1_ioff][3+joff],img->mpr[i1_ioff][2+joff],img->mpr[i1_ioff][1+joff],img->mpr[i1_ioff][joff], img->mpr[i0_ioff][3+joff],img->mpr[i0_ioff][2+joff],img->mpr[i0_ioff][1+joff],img->mpr[i0_ioff][joff]);
temp_m71_sse=_mm_set_epi16(img->mpr[i3_ioff][3+joff],img->mpr[i3_ioff][2+joff],img->mpr[i3_ioff][1+joff],img->mpr[i3_ioff][joff], img->mpr[i2_ioff][3+joff],img->mpr[i2_ioff][2+joff],img->mpr[i2_ioff][1+joff],img->mpr[i2_ioff][joff]);
_asm
_mm_storeu_si128(img_m7,temp_m70_sse);//sse使用專用的結構_m128i,因此最後需要存到我們自己的陣列裡
mmx的32位alpha混合
碰到個古老的問題,畫素的alpha混合,於是查閱了mmx指令,寫出了如下32位畫素格式的alpha混合,不過alpha值固定為半透明,效率還能接受。如下 mov eax,dest dest是目的畫素指標 movd mm0,eax 把目的畫素值移入mm0暫存器的低32位 movd mm1,color ...
SSE的指令系統
sse的指令系統 sse2和sse的指令系統非常相似,僅僅多了少量額外的浮點運算,64位浮點 整數運算支援 sse比傳統浮點運算要快,因為它使用128位儲存單元。在windows使用 include 在linux下使用 include 1.變數定義和使用 m128 s1 s1.m128 f32 2 ...
SSE指令的使用學習
1.什麼是指令集?指令集是為了增強cpu在某些方面 如多 的功能而特意開發出的一組程式 集合。2.常見的指令集有哪些呢?1 mmx multi media extensions,做 擴充套件 指令集 intel1996年推出的一項多 指令增強技術。共包含57條多 指令,這些指令一次可以處理多個資料。...