您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

并行计算一个大向量的和

并行计算一个大向量的和

Boost.Asio的主要目的是为 网络@H_404_4@ 和 I / O编程@H_404_4@ 提供异步模型,您描述的问题似乎与网络和I / O无关。

我认为最简单的解决方案是使用Boost或C ++标准库提供的 线程原语@H_404_4@ 。

这是accumulate仅使用标准库创建的并行版本的示例。

/* Minimum number of elements for multithreaded algorithm.
   Less than this and the algorithm is executed on single thread. */
static const int MT_MIN_SIZE = 10000;

template <typename InputIt, typename T>
auto parallel_accumulate(InputIt first, InputIt last, T init) {
    // Determine total size.
    const auto size = std::distance(first, last);
    // Determine how many parts the work shall be split into.
    const auto parts = (size < MT_MIN_SIZE)? 1 : std::thread::hardware_concurrency();

    std::vector<std::future<T>> futures;

    // For each part, calculate size and run accumulate on a separate thread.
    for (std::size_t i = 0; i != parts; ++i) {
        const auto part_size = (size * i + size) / parts - (size * i) / parts;
        futures.emplace_back(std::async(std::launch::async,
            [=] { return std::accumulate(first, std::next(first, part_size), T{}); }));
        std::advance(first, part_size);
    }

    // Wait for all threads to finish execution and accumulate results.
    return std::accumulate(std::begin(futures), std::end(futures), init,
        [] (const T prev, auto& future) { return prev + future.get(); });
}

[**Live example**](http://coliru.stacked-crooked.com/a/4807261d61b7a726) (并行版本的性能与Coliru上的顺序版本大致相同,可能只有1个内核可用)

在我的机器上(使用8个线程),并行版本平均提高了约120%的性能

顺序求和: 花费时间:46毫秒 5000000050000000 -------------------------------- 并行和: 花费时间:21毫秒 5000000050000000

但是,100,000,000个元素的绝对增益仅为边际(25 ms)。虽然,当累积不同类型的元素时,性能提升可能会大于int

正如@sehe在评论中所提到的,值得一提的是 OpenMP@H_404_4@ 可以为该问题提供简单的解决方案,例如

template <typename T, typename U>
auto omp_accumulate(const std::vector<T>& v, U init) {
    U sum = init;

    #pragma omp parallel for reduction(+:sum)
    for(std::size_t i = 0; i < v.size(); i++) {
        sum += v[i];
    }

    return sum;
}

在我的机器上,此方法的执行效果与使用标准线程基元的并行方法相同。

顺序求和: 花费时间:46毫秒 5000000050000000 -------------------------------- 并行求和: 花费时间:21毫秒 求和:5000000050000000 -------------------------------- OpenMP总和: 花费时间:21毫秒 总和:5000000050000000

其他 2022/1/1 18:16:03 有420人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶