Используя новые инструменты выравнивания C++ 11, я хотел убедиться, что набор временных (стековых) переменных будет находиться в одной строке кэша. Моя первая наивная попытка заключалась в следующем:Переменные стека в кэше
int main() {
alignas(64) int a; // 0x7fffc58aac80, properly aligned at 64
int b; // 0x7fffc58aac7c
int c; // 0x7fffc58aac78
return 0;
}
Глупо мне! Stack не выделяет переменные таким образом, таким образом a
будет в другой строке кэша, чем b
и c
.
Означает ли это, что метод позволяет правильно выровнять несколько переменных через совокупность?
struct alignas(64) Abc {
int x;
int y;
int z;
};
int main() {
Abc foo;
// x 0x7fff40c2d3c0 (aligned at 64)
// y 0x7fff40c2d3c4
// z 0x7fff40c2d3c8
return 0;
}
Компилятор: Clang 3.2
Вы действительно думаете, что если все эти переменные в одной строке кэша улучшат производительность? Коэффициенты довольно хороши, что стек находится в кеше. –
Он * может * оказать влияние, если эти переменные должны быть разделены между несколькими ядрами, так что, какой бы ядро не захотел писать им, необходимо использовать все три переменные за раз. Если все они лежат в одной и той же строке кэша, и доступ к этой переменной встречается редко, трафик когерентности будет уменьшен. Однако нет никакой гарантии, что строка может быть недействительной между чтением двух переменных в одной строке. –
Современные компиляторы даже не фиксируют переменные стека в фиксированном месте (если вы не берете их адрес, конечно). Поэтому, если 'a' и' b' разделяли строку кэша, после записи в файл, который может измениться. (Это типично для оптимизации статического одиночного присваивания) – MSalters