-1

我正在编写一个多线程代码,其中一堆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+在重构我的代码以避免对and的不必要调用之后operator-,我似乎获得了更好的扩展性。

4

1 回答 1

3

是的,可能会放缓。主内存 (RAM) 带宽是有限的,如果您有多个内核快速读取大量数据,您可能会使内存总线饱和。最大内存带宽通常为每秒数十 GB(请参阅特定处理器的页面,例如i9-9900K,它显示为 41.6 GB/s)。

同样,一个物理包上的所有内核共享一个 L3 缓存,因此如果您多次读取某些数据,您的缓存命中可能会更少,因为您的线程将彼此的数据推出 L3(这是最大的缓存)。

如果您想知道某些配置有多少减速,您只有一个选择:测试它们。如果您提前知道您可能需要什么内存,请考虑将预取指令添加到您的代码中,特别是如果您的访问模式是非顺序的。

于 2021-01-16T05:06:39.773 回答