Aligning Class Members in C++11
I'm trying to align class members to specific alignments (eg, 128) in C++11 to avoid false sharing between threads. Мой подход заключается в использовании alignas
but I'm getting mixed results. In this simple program, I'm getting the results I desire:
#include <cstdio>
#include <atomic>
struct Foo {
char foo[128];
void* x1;
uint32_t x2;
uint32_t x3; // here an "entry" is only the
alignas(128) std::atomic<unsigned int> a;
alignas(16) std::atomic<unsigned int> b;
};
int main(int argc, char const *argv[])
{
Foo x, y;
printf("alignof(Foo x) = %zu\n", alignof(x));
printf("alignof(Foo x.a) = %zu\tmod 128 = %d\n", alignof(x.a), reinterpret_cast<uintptr_t>(&(x.a)) % 128);
printf("alignof(Foo x.b) = %zu\tmod 16 = %d\n", alignof(x.b), reinterpret_cast<uintptr_t>(&(x.b)) % 16);
/* code */
return 0;
}
However, in a larger program with a very similar class structure, and also using alignas
до 128 байт. Когда я распечатаю alignof
из полей, я получаю то, что я ожидаю, и что я указал в alignas
приписывать. Однако, когда я изменяю адрес соответствующих полей, я не получаю того же значения, что и alignas
Аргумент (128) - я получаю 32. Я ожидаю alignas
поместить переменную в память в начале адреса памяти, который делится равномерно на 128; это ожидание верно?
Обратите внимание, что в приведенной ниже программе я получаю ожидаемые результаты при компиляции clang 6.0.1. Я не могу опубликовать эту большую программу, потому что она очень большая и не может быть опубликована. Я также не смог придумать тестовую программу, которая повторяет конкретную проблему, но я продолжаю пробовать.
Вопросы:
- Является ли мой подход к выравниванию определенных членов в классе рекомендуемым для C++11?
- Если нет, то как правильно? Добавляет фиктивные поля, такие как
char _pad[120]
путь? - Должен ли я выравнивать сам класс? Прямо сейчас я не делаю этого явно.