微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

即使没有锁也会有内存争用吗?

如何解决即使没有锁也会有内存争用吗?

我正在编写一个多线程代码,其中一堆 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- 进行不必要的调用后,我似乎得到了更好的扩展。

解决方法

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

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

如果您想知道某些配置的减速程度,您只有一种选择:测试它们。如果您提前知道可能需要哪些内存,尤其是在您的访问模式是非顺序的情况下,请考虑向您的代码添加预取指令。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。