Обычный вариант использования спецификатора alignas
— сценарий, в котором вы хотите передать несколько объектов между разными потоками через очередь (например, очередь событий или задач), избегая при этом ложный обмен. Ложное совместное использование произойдет из-за того, что несколько потоков конкурируют за одну и ту же строку кэша, хотя на самом деле они обращаются к разным объектам. Обычно это нежелательно из-за снижения производительности.
Например, при условии, что размер строки кэша составляет 64 байт, для следующего класса Event
:
struct Event {
int event_type_;
};
Выравнивание Event
будет соответствовать выравниванию его элемента данных event_type_
. Если предположить, что выравнивание int
равно 4 байтам (т. е. alignof(int)
оценивается как 4), то до 16 Event
объектов может поместиться в один строка кэша. Итак, если у вас есть очередь, например:
std::queue<Event> eventQueue;
Когда один поток помещает события в конец очереди, а другой поток извлекает события из начала, у нас может быть, что оба потока конкурируют за одну и ту же строку кэша. Однако при правильном использовании спецификатора alignas
для Event
:
struct alignas(64) Event {
int event_type_;
};
Таким образом, объект Event
всегда будет выравниваться по границе строки кэша, так что строка кэша будет содержать максимум объект Event
. Поэтому два или более потока никогда не будут конкурировать за одну и ту же строку кэша при доступе к различным объектам Event
(если несколько потоков обращаются к одному и тому же объекту Event
, они, очевидно, будут конкурировать за одну и ту же строку кэша).
person
眠りネロク
schedule
20.06.2020