OpenMP 并行 For 循环中 std::vector 的替代品
在 OpenMP 中,在并行 for 中使用共享 std::vector循环可能会带来性能挑战。本文探讨了具有速度优势的潜在替代方案,特别是在循环执行期间需要调整大小时。
候选替代方案
std ::具有 OpenMP Reduction 的向量:
此方法涉及使用使用#pragma omp declareduction 声明的用户定义的归约。下面的代码演示了如何应用它来并行组合向量:
#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:
如果保留元素的顺序至关重要,则可以采用此技术。它利用静态时间表和有序部分以所需的顺序插入向量:
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()); } }
前缀求和方法:
此方法避免为每个线程存储向量,而是选择并行合并的单个向量。它利用前缀和数组来跟踪插入点:
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;
这些替代方案提供了在 OpenMP 环境中使用并行 for 循环和调整向量大小的有效且高效的方法,超越了限制由 std::vector 提出。
以上是使用 OpenMP 并行 for 循环时,尤其是需要调整大小时,'std::vector”的有效替代方案是什么?的详细内容。更多信息请关注PHP中文网其他相关文章!