Если `atomic <T>` не блокируется и имеет тот же размер, что и `T`, будет ли структура памяти такой же? - PullRequest
4 голосов
/ 02 мая 2019

Этот вопрос здесь указывает, что std::atomic<T> - это , как правило, должен иметь тот же размер, что и T, и действительно, похоже, это относится к gcc, clang и msvc на x86, x64 и ARM.

В реализации, где std::atomic<T> всегда свободен от блокировки для некоторого типа T, гарантированно ли его расположение памяти совпадает с расположением памяти T? Существуют ли какие-либо дополнительные специальные требования, налагаемые std::atomic, такие как выравнивание?

Ответы [ 2 ]

5 голосов
/ 02 мая 2019

После просмотра [atomics.types.generic] , в ответе которого вы связали цитаты частично, единственное замечание относительно выравнивания - это заметка, которую вы видели раньше:

Примечание: представление атомарной специализации не обязательно должно иметь тот же размер, что и соответствующий ему тип аргумента.Специализации должны иметь одинаковый размер, когда это возможно, так как это уменьшает усилия, необходимые для переноса существующего кода

В более новой версии:

Представление атомарной специализации не нужноимеют те же требования к размеру и выравниванию, что и соответствующий тип аргумента.

Более того, по крайней мере, одна архитектура, IA64, дает требование для атомарного поведения инструкций, таких как cmpxchg.acq, что указывает на то, что вполне вероятно, что компилятору, ориентированному на IA64, может потребоваться выровнять атомарные типы иначе, чем неатомарные типы, даже при отсутствии блокировки.

Кроме того, использование функции компилятора, такой как упакованные структурыприведет к разнице в выравнивании между атомарными и неатомарными вариантами.Рассмотрим следующий пример:

#include <atomic>
#include <iostream>
struct __attribute__ ((packed)) atom{
    char a;
    std::atomic_long b;
};
struct __attribute__ ((packed)) nonatom{
    char a;
    long b;
};

atom atom1;
nonatom nonatom1;
int disp_aligns(int num) {
    std::cout<< alignof(atom1.b) << std::endl;
    std::cout<< alignof(nonatom1.b) << std::endl;
}

На хотя бы в одной конфигурации , выравнивание atom1.b будет на 8-байтовой границе, а выравнивание nonatom1.b будетна 1-байтовой границе.Однако, это предположение, что мы просили, чтобы структуры были упакованы;не ясно, интересует ли вас этот случай.

4 голосов
/ 02 мая 2019

Из стандарта :

Представление атомарной специализации не обязательно должно иметь те же требования к размеру и выравниванию, что и соответствующий ему тип аргумента.

Таким образом, ответ, по крайней мере, на данный момент, - нет, не гарантируется, что он будет одинакового размера и одинакового выравнивания. Но это может произойти, если это не так, и тогда не будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...