保护成员变量的错误共享

False sharing of guarded member variables?

本文关键字:错误 共享 变量 成员 保护      更新时间:2023-10-16

考虑:

class Vector
{
  double x, y, z;
  // …
};
class Object
{
  Vector Vec1, Vec2;
  std::mutex Mtx1, Mtx2;
  void ModifyVec1() { std::lock_guard Lock(Mtx1); /* … */ }
  void ModifyVec2() { std::lock_guard Lock(Mtx2); /* … */ }
};

如果互斥对象或保护变量是连续存储的,并且它们在缓存时共享一个缓存行,这会导致某种"交叉锁定"吗?

如果是这样,那么在互斥锁所保护的变量之后(或之前(声明互斥锁是一种好的做法吗?

将类与std::hardware_destructive_interference_size(P0154(对齐可以避免这种影响。对象的过度对齐是否值得潜在的好处?

您的问题中的变量似乎不相关,因此您可能想要的不是hardware_destructive_interference_size,而是hardware_constructive_interference_size:

struct keep_together {
    std::mutex m;
    Vector v;
};
alignas(std::hardware_constructive_interference_size) keep_together k1;
alignas(std::hardware_constructive_interference_size) keep_together k2;

如果线程正在读取两个不同的atomic,并且您希望确保它们都被实际加载,那么您希望将destructive用于无锁队列之类的情况。如果这是一个问题,你需要解释为什么你要避免虚假分享。

在互斥锁保护的变量之后(或之前(声明互斥锁,以增加它们在同一缓存线上的机会,这是一种好的做法吗?

这是constructive干扰。