Ложный обмен защищенными переменными-членами?

Рассматривать:

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

4

Решение

Ваши переменные кажутся несвязанными в вашем вопросе, а не 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 вмешательство.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]