【发布时间】:2021-01-16 04:37:30
【问题描述】:
我正在编写一个多线程代码,其中一堆std::async 调用在整个程序期间生成固定数量的线程。每个线程都以只读方式处理相同的const BigData 结构。有来自const BigData 的频繁随机读取,但线程在其他方面是完全独立的。是否可以合理地期望获得完美的扩展,或者是否会因更多的内存访问而减慢?
编辑:经过一些分析,这似乎是罪魁祸首:
class Point {
friend Point operator+(const Point& lhs, const Point& rhs) noexcept {
return Point{lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z};
};
friend Point operator-(const Point& lhs, const Point& rhs) noexcept {
return Point{lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z};
};
public:
Point() noexcept;
Point(const Real& x, const Real& y, const Real& z) noexcept
: x{x}, y{y}, z{z} {};
private:
Real x{0};
Real y{0};
Real z{0};
};
在重构我的代码以避免对operator+ 和operator- 的不必要调用后,我似乎获得了更好的扩展性。
【问题讨论】:
-
有足够多的未指定参数(读取大小、缓存行为、与 NUMA 相关的任何内容等)我们无法给出明确的答案。最好的办法是进行实验,看看性能如何扩展。
-
如果您看到速度大幅下降,我会感到惊讶,因为数据的只读性质应该允许每个 CPU 缓存它自己正在访问的任何页面的本地副本。当然,如果您的 CPU 内核共享一个缓存,并且它们一起填满该缓存,以便它们反复将彼此的页面踢出缓存以加载自己的缓存,这将导致一些速度变慢(相对于理论上的最佳性能,无论如何)。
标签: c++ multithreading contention