Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Melaksanakan Pengurangan Array dengan Cekap dalam OpenMP?
Menyelesaikan Pengurangan Tatasusunan dalam OpenMP
Dalam OpenMP, pengurangan secara langsung pada tatasusunan tidak disokong. Walau bagaimanapun, kaedah alternatif wujud untuk mencapai hasil yang serupa.
Kaedah Pertama:
Satu pendekatan melibatkan mencipta salinan peribadi tatasusunan untuk setiap urutan dan mengurangkannya secara setempat. Selepas bahagian selari, gabungkan tatasusunan peribadi ke dalam tatasusunan asal menggunakan bahagian kritikal untuk mengelakkan perlumbaan data.
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:
Cara lain ialah dengan peruntukkan tatasusunan yang lebih besar dengan dimensi yang sama dengan saiz tatasusunan didarab dengan bilangan utas. Setiap benang kemudian mengisi bahagian tatasusunannya. Selepas bahagian selari, gabungkan nilai ke dalam tatasusunan asal tanpa menggunakan bahagian kritikal.
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]; } } }
Kaedah kedua adalah lebih cekap, terutamanya dalam senario yang melibatkan berbilang soket, tetapi ia juga memerlukan pengendalian memori yang teliti untuk mengelakkan isu cache.
Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Pengurangan Array dengan Cekap dalam OpenMP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!