Alternatif kepada std::vector dalam OpenMP Parallel For Loop
Dalam OpenMP, bekerja dengan std::vektor kongsi secara selari untuk gelung boleh menimbulkan cabaran prestasi. Artikel ini meneroka alternatif berpotensi yang menawarkan kelebihan kelajuan, terutamanya apabila saiz semula diperlukan semasa pelaksanaan gelung.
Alternatif Calon
std ::vektor dengan Pengurangan OpenMP:
Pendekatan ini melibatkan menggunakan pengurangan yang ditentukan pengguna yang diisytiharkan dengan #pragma omp declare pengurangan. Kod di bawah menunjukkan cara ia boleh digunakan untuk menggabungkan vektor secara selari:
#pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) std::vector<int> vec; #pragma omp parallel for reduction(merge: vec) for (int i = 0; i < 100; i++) vec.push_back(i);
std::vector dengan Penjadualan Statik dan Sisipan Tertib:
Jika mengekalkan susunan unsur adalah kritikal, teknik ini boleh digunakan. Ia menggunakan jadual statik dan bahagian tersusun untuk memasukkan vektor dalam urutan yang dikehendaki:
std::vector<int> vec; #pragma omp parallel { std::vector<int> vec_private; #pragma omp for nowait schedule(static) for (int i = 0; i < N; i++) vec_private.push_back(i); #pragma omp for schedule(static) ordered for (int i = 0; i < omp_get_num_threads(); i++) { #pragma omp ordered vec.insert(vec.end(), vec_private.begin(), vec_private.end()); } }
Kaedah Jumlah Awalan:
Kaedah ini mengelak daripada menyimpan vektor untuk setiap utas, memilih untuk satu vektor digabungkan secara selari. Ia memanfaatkan tatasusunan jumlah awalan untuk menjejak titik sisipan:
std::vector<int> vec; size_t *prefix; #pragma omp parallel { int ithread = omp_get_thread_num(); int nthreads = omp_get_num_threads(); #pragma omp single { prefix = new size_t[nthreads + 1]; prefix[0] = 0; } std::vector<int> vec_private; #pragma omp for schedule(static) nowait for (int i = 0; i < 100; i++) vec_private.push_back(i); prefix[ithread + 1] = vec_private.size(); #pragma omp barrier #pragma omp single { for (int i = 1; i < (nthreads + 1); i++) prefix[i] += prefix[i - 1]; vec.resize(vec.size() + prefix[nthreads]); } std::copy(vec_private.begin(), vec_private.end(), vec.begin() + prefix[ithread]); } delete[] prefix;
Alternatif ini menyediakan cara yang berkesan dan cekap untuk bekerja dengan selari untuk gelung dan mengubah saiz vektor dalam persekitaran OpenMP, melepasi batasan ditimbulkan oleh std::vector.
Atas ialah kandungan terperinci Apakah alternatif yang cekap untuk `std::vector` apabila menggunakan OpenMP selari untuk gelung, terutamanya apabila saiz semula diperlukan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!