2016-09-16 6 views
4

Рассмотрим:Ложное разделение охраняемых переменных-членов?

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) может избежать этого эффекта. Возможны ли потенциальные выгоды для переоценки объекта?

+0

Стандарт C++ не требует, чтобы классы были выложены в любом конкретном порядке (с некоторыми оговорками, которые здесь не применимы). Вы можете определить из документации вашего компилятора, использует ли он детерминированный порядок для членов класса (вероятно). –

+3

@SamVarshavchik Для класса стандартного макета они должны быть в порядке декларации и в зависимости от того, что опубликовано до сих пор, это может быть стандартный класс макета. Также это не имеет особого значения, поскольку OP задает вопрос о деталях конкретных реализаций –

+0

@ Rakete1111 Пожалуйста, не стесняйтесь редактировать – metalfox

ответ

3

Вашего переменные кажется не связаны в вашем вопросе, так что вместо 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; 

destructive вы хотите использовать в тех случаи, как безблокировочные очереди, были потоки чтение двух различных atomic с и вы хотите убедиться, что они оба загружены. Если это проблема, вам нужно объяснить, почему ложный обмен - это то, чего вы избегаете.

Полезно ли объявлять мьютекс сразу после (или до) переменной, которую она защищает, чтобы увеличить вероятность того, что они находятся на одной линии кэша?

Это constructive помех.

+0

Спасибо за разъяснение. Я смешивал обе концепции. Я хотел бы поощрять настоящий обмен, но также и препятствовать ложному обмену, если это может произойти. Представьте, что мьютексы хранятся смежно. Могут ли они использовать линию кэша? Я отредактировал вопрос, надеюсь, сделать его более ясным. – metalfox

Смежные вопросы