- 并行編程方法與優化實踐
- 劉文志
- 757字
- 2019-01-01 01:08:28
1.1.1 算術運算
SSE內置函數中支持的算術操作如表1-1所示。從表中可以看出,SSE幾乎支持所有常用的算術運算。故可以預知:大多數算法只要滿足向量化數據并行的特點,就有可能能夠使用SSE指令進行向量化。
表1-1 SSE算術運算
表1-1中有一些不太常見的指令,本節簡要介紹一些。
hadd表示將一個向量相鄰的兩個元素相加,并要保持原來的向量大小。因此它具有兩個參數,如下例所示:
__m128 _mm_hadd_ps(__m128 a, __m128 b); r[0] = a[0]+a[1]; r[1] = a[2]+a[3]; r[2] = b[0]+b[1]; r[3] = b[2]+b[3]; __m128 _mm_addsub_ps(__m128 a, __m128 b); r[0] = a[0]-a[1]; r[1] = a[2]+a[3]; r[2] = b[0]-b[1]; r[3] = b[2]+b[3];
其中:r表示結果,使用數組表示法就是表示向量中的第幾個元素,如[2]表示其為向量寄存器中保存的第三個元素。
使用hadd能夠比較容易地實現多個向量求內積,如代碼清單1-1所示。
代碼清單1-1 使用hadd求向量內積
__m128 a = _mm_mul_ps(b, c); __m128 zero = _mm_setzero_ps(); a = _mm_hadd_ps(a, zero); a = _mm_hadd_ps(a, zero);
運算完成后,a中的第一個元素即為b、c兩個向量的內積。
其實addsub應該寫作subadd,因為第一個操作是減法。hsub和hadd類似,只是執行的運算是減法。
比較有意思的是dp操作,對于單精度浮點類型的數據,其定義如下:
__m128 _mm_dp_ps(__m128 a, __m128 b, const int mask); __m128 tmp; tmp[0] = (mask[4]==1) ? (a[0]*b[0]) : 0.0; tmp[1] = (mask[5]==1) ? (a[1]*b[1]) : 0.0; tmp[2] = (mask[6]==1) ? (a[2]*b[2]) : 0.0; tmp[3] = (mask[7]==1) ? (a[3]*b[3]) : 0.0; __mm32 tmp4 tmp4 = tmp[0] + tmp[1] + tmp[2] + tmp[3]; r[0] = (mask[0]==1) ? tmp4 : 0.0; r[1] = (mask[1]==1) ? tmp4 : 0.0; r[2] = (mask[2]==1) ? tmp4 : 0.0; r[3] = (mask[3]==1) ? tmp4 : 0.0;
很明顯,一條dp操作可以直接實現兩個向量的內積運算,如代碼清單1-2所示。
代碼清單1-2 使用dp操作實現兩個向量的內積運算
int mask = 1+(1<<4)+(1<<5)+(1<<6)+(1<<7); __m128 r = _mm_dp_ps(b, c, mask);
blend和blendv操作類似于C/C++中的三目運算符(?:),blend依據掩碼的位選擇,而blendv依據掩碼向量中各元素的符號位選擇,示例如下:
__m128 _mm_blend_ps(__m128 a, __m128 b, const int mask); r[0] = (mask[0]==0) ? a[0] : b[0]; r[1] = (mask[1]==0) ? a[1] : b[1]; r[2] = (mask[2]==0) ? a[2] : b[2]; r[3] = (mask[3]==0) ? a[3] : b[3]; __m128 _mm_blendv_ps(__m128 a, __m128 b, __m128 mask); r[0] = (mask[0]&0x80000000) ? b[0] : a[0]; r[1] = (mask[1]&0x80000000) ? b[1] : a[1]; r[2] = (mask[2]&0x80000000) ? b[2] : a[2]; r[3] = (mask[3]&0x80000000) ? b[3] : a[3];
很容易想到,可以使用blendv向量化一些簡單的分支運算,如代碼清單1-3所示。
代碼清單1-3 簡單的可向量化的分支運算示例
for(int i = 0; i < n; i++){ r[i] = a[i] > 0 ? b[i]:c[i]; }
這同時要求許多比較指令返回結果的符號位為0或1。
推薦閱讀
- C及C++程序設計(第4版)
- JavaScript百煉成仙
- Visual Studio 2012 Cookbook
- Mastering Objectoriented Python
- Functional Kotlin
- Java程序設計
- Unity 2018 Augmented Reality Projects
- Android應用開發實戰(第2版)
- 進入IT企業必讀的324個Java面試題
- Mastering Embedded Linux Programming
- Solr權威指南(下卷)
- Python深度學習(第2版)
- HTML5程序設計基礎教程
- Spring Boot 2+Thymeleaf企業應用實戰
- Python程序設計現代方法