Elv*_*vis 6 c++ multithreading scalability
这是一个用于多线程向量和的C++ 11代码.
#include <thread>
template<typename ITER>
void sum_partial(ITER a, ITER b, double & result) {
result = std::accumulate(a, b, 0.0);
}
template<typename ITER>
double sum(ITER begin, ITER end, unsigned int nb_threads) {
size_t len = std::distance(begin, end);
size_t size = len/nb_threads;
std::vector<std::thread> thr(nb_threads-1);
std::vector<double> r(nb_threads);
size_t be = 0;
for(size_t i = 0; i < nb_threads-1; i++) {
size_t en = be + size;
thr[i] = std::thread(sum_partial<ITER>, begin + be, begin + en, std::ref(r[i]));
be = en;
}
sum_partial(begin + be, begin + len, r[nb_threads-1]);
for(size_t i = 0; i < nb_threads-1; i++)
thr[i].join();
return std::accumulate(r.begin(), r.end(), 0.0);
}
Run Code Online (Sandbox Code Playgroud)
典型的用途是sum(x.begin(), x.end(), n)使用x双精度矢量.
这是一个图表,显示计算时间作为线程数的函数(求和10⁷值的平均时间,在没有其他运行的8核计算机上 - 我尝试在32核计算机上,行为非常相似).
为什么可扩展性如此差?可以改进吗?
我(非常有限)的理解是,为了具有良好的可伸缩性,线程应避免在同一缓存行中写入.这里所有线程都写入r一次,在计算结束时,我不认为它是限制因素.这是内存带宽问题吗?