如何解决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 举报,一经查实,本站将立刻删除。