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] путь?
  • Должен ли я выравнивать сам класс? Прямо сейчас я не делаю этого явно.

0 ответов

Другие вопросы по тегам