首页 > 后端开发 > C++ > 使用 OpenMP 并行 for 循环时,尤其是需要调整大小时,'std::vector”的有效替代方案是什么?

使用 OpenMP 并行 for 循环时,尤其是需要调整大小时,'std::vector”的有效替代方案是什么?

Susan Sarandon
发布: 2024-11-29 08:03:09
原创
549 人浏览过

What are the efficient alternatives to `std::vector` when using OpenMP parallel for loops, especially when resizing is needed?

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板