C++ 保护成员变量的错误共享?
考虑:C++ 保护成员变量的错误共享?,c++,c++11,mutex,c++17,false-sharing,C++,C++11,Mutex,C++17,False Sharing,考虑: 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); /* … */ } }; 如果互斥体或受保护的变量连续存储
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\u destroctive\u interference\u size
()对齐可以避免这种影响。潜在的好处是否值得对象的过度对齐?在您的问题中,您的变量似乎不相关,因此您可能希望硬件\u破坏性\u干扰\u大小
而不是硬件\u构造性\u干扰\u大小
:
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;
破坏性
您希望用于无锁队列之类的情况,如果线程正在读取两个不同的原子
并且您希望确保它们都被实际加载。如果这是一个问题,你需要解释为什么虚假分享是你要避免的
在它所保护的变量之后(或之前)声明互斥体是否是一种好的做法,以增加它们位于同一缓存线上的可能性
这是建设性的干扰 C++标准不要求按任何特定的顺序排列类成员(这里有一些警告是不适用的)。您可以从编译器的文档中确定它是否对类成员使用确定性顺序(可能)。@SamVarshavchik对于标准布局类,它们必须按照声明顺序,并且根据目前发布的内容,这可能是一个标准布局类。同样,这并不重要,因为OP询问的是特定项目的细节implementations@Rakete1111请随时联系我们edit@metalfox等等,什么?我只是“回答”了你的第一个问题:)与其把它们按变量上面的特定顺序排列,不如给它们起个名字,让它们明白互斥锁保护着这个特定变量。@Rakete1111问题是关于成员顺序如何影响缓存,不是为了让人类读者清楚地了解成员之间的关系。谢谢你的澄清。我混合了这两个概念。我想鼓励真正的分享,但也不鼓励错误的分享,以防它发生。假设互斥量是连续存储的。他们可能共享缓存线吗?我编辑了这个问题,希望能让它更清楚。