C++ std 库并行执行 for_each 比顺序循环慢

标签 c++ c++17 parallel-execution

自 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(), rez.end(),
      [&](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(), rez.end(), 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

问题,

  • 相对于 1 个工作人员,性能没有提升,为什么?

最佳答案

我认为,对于少量工作,可能会出现这样的情况:通过纯粹保留在 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

关于C++ std 库并行执行 for_each 比顺序循环慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64324386/

相关文章:

c++ - std::function 无法区分重载函数

c++ - 这是重载提供与非静态成员函数相同接口(interface)的静态成员函数的优雅方法吗?

c++ - 超出命名空间函数定义的参数类型查找

ssis - SSIS如何选择并行执行的数据流任务?

c++ - 如何在 int 类型的 vector 中使用 lambda?

c++ - 从 C++ 编译器获取可读的错误消息

c++ - 为什么 C++17 标准没有带来部分类模板参数推导?

java - 如何在多台机器上并行执行 testNG 测试用例?

python - 如何一次并行执行多个pytest套件(文件)

c++ - 如何修复 "Error LNK2019 : unresolved external symbol ... "