Mengurangkan Tatasusunan dalam OpenMP
Tidak mungkin untuk melakukan pengurangan secara langsung pada tatasusunan dalam OpenMP. Walau bagaimanapun, terdapat pendekatan alternatif untuk mencapai paralelisme pengurangan tatasusunan.
Kaedah Pertama: Tatasusunan Peribadi dan Bahagian Kritikal
Kaedah ini mencipta salinan peribadi tatasusunan untuk setiap urutan. Setiap urutan mengisi tatasusunan peribadinya dan bahagian kritikal digunakan untuk menggabungkan keputusan ke dalam tatasusunan akhir.
int A[] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13}; int S[10] = {0}; #pragma omp parallel { int S_private[10] = {0}; #pragma omp for for (int n = 0; n < 10; ++n) { for (int m = 0; m <= n; ++m) { S_private[n] += A[m]; } } #pragma omp critical { for(int n = 0; n < 10; ++n) { S[n] += S_private[n]; } } }
Kaedah Kedua: Pengembangan Tatasusunan dan Pengumpulan Bebas Benang
Kaedah ini mencipta tatasusunan yang diperluaskan yang merangkumi semua urutan. Setiap benang mengisi bahagian tatasusunannya, dan kemudian hasilnya digabungkan tanpa menggunakan bahagian kritikal. Pendekatan ini boleh menyebabkan masalah cache jika tidak digunakan dengan berhati-hati pada sistem berbilang soket.
int A[] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13}; int S[10] = {0}; int *S_private; #pragma omp parallel { const int nthreads = omp_get_num_threads(); const int ithread = omp_get_thread_num(); #pragma omp single { S_private = new int[10 * nthreads]; for(int i = 0; i < (10 * nthreads); i++) S_private[i] = 0; } #pragma omp for for (int n = 0; n < 10; ++n) { for (int m = 0; m <= n; ++m){ S_private[ithread * 10 + n] += A[m]; } } #pragma omp for for(int i = 0; i < 10; i++) { for(int t = 0; t < nthreads; t++) { S[i] += S_private[10 * t + i]; } } } delete[] S_private;
Atas ialah kandungan terperinci Bagaimanakah Pengurangan Susunan Boleh Disejajarkan dalam OpenMP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!