微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C ++标准库并行执行的for_each速度比顺序循环慢

如何解决C ++标准库并行执行的for_each速度比顺序循环慢

自c ++ 17起,std库具有并行算法,因此我尝试使用以下代码,对数字列表求和,并希望查看是否有任何性能提升。

#include <algorithm>
#include <chrono>
#include <execution>
#include <numeric>
#include <iostream>
#include <vector>

int main() {
  size_t n = 100000000;
  std::vector<size_t> vec(n);
  std::iota(vec.begin(),vec.end(),0);

  auto par_sum = [&](size_t k) {
    auto t1 = std::chrono::high_resolution_clock::Now();

    std::vector<size_t> rez(k);
    std::iota(rez.begin(),rez.end(),0);
    size_t batch = static_cast<size_t>(n / k) + 1;
    std::for_each(std::execution::par_unseq,rez.begin(),[&](size_t id) {
        size_t cum = 0;
        for (size_t i = id*batch; i < std::min((id+1)*batch,n); ++i) {
          cum += vec[i];
        }
        rez[id] = cum;
    });

    auto t2 = std::chrono::high_resolution_clock::Now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
    std::cout << "n_worker = " << k
      << ",time = " << duration
      << ",rez = " << std::accumulate(rez.begin(),0lu)
      << std::endl;
  };

  par_sum(1);
  par_sum(3);
  par_sum(5);
}

编译者

g++  -std=c++17 -L/usr/local/lib -O3 -mavx -ltbb a.cpp

结果表明

n_worker = 1,time = 51875,rez = 4999999950000000
n_worker = 3,time = 57616,rez = 4999999950000000
n_worker = 5,time = 63193,rez = 4999999950000000

问题,

  • 没有对一名工人的绩效提升,为什么?

解决方法

我认为对于少量的工作,可能会发生这样的情况:仅通过将其保留在L1缓存上下文中,就可以在一个CPU中执行紧密循环。一旦增加了相同数据上的并行度 ,您就会开始调用具有缓存一致性和页面错误的开销。

您可能值得考虑一下计算高速缓存未命中次数的方法,例如以下建议的方法: Programmatically counting cache faults

,另请参阅: What is a "cache-friendly" code?

以及有关“缓存友好代码”和“面向数据的设计”的其他资源: https://www.youtube.com/watch?v=b5v9aElYU2I

https://youtu.be/fHNmRkzxHWs

这与 虚假共享 有关,在此处进行了说明: https://www.youtube.com/watch?v=dznxqe1Uk3E

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。