我正在尋找有關(guān)如何使用SSE進行并行前綴求和的建議。我有興趣在整數(shù),浮點數(shù)或雙精度數(shù)組上執(zhí)行此操作。我提出了兩種解決方案。特殊情況和一般情況。在這兩種情況下,解決方案都需要與OpenMP并行進行兩次遍歷。對于特殊情況,我在兩次通過時都使用SSE。對于一般情況,我僅在第二遍使用它。我的主要問題是,在一般情況下,如何在第一次通過時使用SSE? 以下鏈接simd-prefix-sum-intel-cpu顯示了對字節(jié)的改進,但對32位數(shù)據(jù)類型卻沒有。特殊情況被稱為特殊情況的原因是,它要求數(shù)組采用特殊格式。例如,假設(shè)a浮點數(shù)組只有16個元素。然后,如果數(shù)組是這樣重新排列的(從結(jié)構(gòu)數(shù)組到數(shù)組結(jié)構(gòu)):a[0] a[1] ...a[15] -> a[0] a[4] a[8] a[12] a[1] a[5] a[9] a[13]...a[3] a[7] a[11] a[15]兩次通過均可以使用SSE垂直總和。但是,這只有在數(shù)組已經(jīng)采用特殊格式并且輸出可以采用特殊格式的情況下才有效。否則,必須在輸入和輸出上都進行昂貴的重新排列,這將使其比一般情況慢得多。也許我應(yīng)該考慮使用不同的前綴總和算法(例如,二叉樹)?一般情況的代碼:void prefix_sum_omp_sse(double a[], double s[], int n) { double *suma; #pragma omp parallel { const int ithread = omp_get_thread_num(); const int nthreads = omp_get_num_threads(); #pragma omp single { suma = new double[nthreads + 1]; suma[0] = 0; } double sum = 0; #pragma omp for schedule(static) nowait //first parallel pass for (int i = 0; i<n; i++) { sum += a[i]; s[i] = sum; } suma[ithread + 1] = sum; #pragma omp barrier #pragma omp single { double tmp = 0; for (int i = 0; i<(nthreads + 1); i++) { tmp += suma[i]; suma[i] = tmp; } } __m128d offset = _mm_set1_pd(suma[ithread]); #pragma omp for schedule(static) //second parallel pass with SSE as well for (int i = 0; i<n/4; i++) { __m128d tmp1 = _mm_load_pd(&s[4*i]); tmp1 = _mm_add_pd(tmp1, offset); __m128d tmp2 = _mm_load_pd(&s[4*i+2]); tmp2 = _mm_add_pd(tmp2, offset); _mm_store_pd(&s[4*i], tmp1); _mm_store_pd(&s[4*i+2], tmp2); } } delete[] suma;}
- 1 回答
- 0 關(guān)注
- 540 瀏覽
添加回答
舉報
0/150
提交
取消