Некоторые тривиальные типы в C++ не имеют unique_representation, для них std::has_unique_object_representations_v является ложным, это означает, что эквивалентные значения могут не быть равными по битам memcmp.
Один Одной из причин этого является наличие битов заполнения. Биты заполнения — это неиспользуемые биты битового поля, байты выравнивания структуры или дополнительное заполнение, скажем, для 10-байтового числа с плавающей запятой.
C++2a исключил заполнениеatomic::compare_exchange_strong Сравнение и Compare_exchange_weak. См.:
- Основное предложение P0528R3
Загадочный случай заполнения битов с использованием атомарного сравнения и обмена
< li>Ссылка изatomic_ref 5. Проблемы с атомарными битами и битами заполнения в T
- Один из способов сделать это — очистить биты заполнения из исходного значения в конструктор, сохраните, обменяйте и очистите нужное значение в Compare_exchange_*. Таким образом, кажется, что конструкторatomic_ref должен быть атомарным, и существует «плата за то, что вы не используете», если операция Compare_exchange не используется.
- Другой способ Я вижу, что нужно скопировать биты заполнения из наблюдаемого значения в цикле Compare_exchange. Таким образом, цикл CAS завершается только при несовпадении битов значений. Кажется, что это противоречит цели разделения на сильную и слабую CAS, поскольку слабая CAS не должна постоянно давать сбои, а при таком подходе это может произойти. Хотя CAS на основе LL/SC, похоже, способен выполнять внутреннее сравнение с естественным исключением бита заполнения, поэтому возможен слабый CAS без цикла.
- Какой из подходов (если есть) правильный? Существуют ли другие правильные подходы?
- Если несколько подходов верны, какой из них обычно более эффективен?
Обратите внимание, что существует простой способ получить ненулевые биты заполнения:
struct S {
int i : 17;
};
S* s = (S*)malloc(sizeof(S));
s->i = 1;
struct S2 {
std::uint8_t j;
std::uint16_t k;
};
S2* s2 = (S2*)malloc(sizeof(S2));
s2->j = 2;
...
s2->k = 3;
Подробнее здесь: https://stackoverflow.com/questions/629 ... c-with-pad