Я строю кроссплатформенный слой атомной абстракции, чтобы поддержать 64-разрядные и 128-битные атомные операции для следующих типов: < /p>
- int64_t, uint64_t < /p>
< /li>
int64_t, uint64_t < /p>
. (на платформах Clang) < /p>
< /li>
Custom MyInt128 struct (используется на MSVC для эмуляции 128-битных целых чисел как два int64_ts) < /p>
< /li>
< /ul>
платформы, которые мне нужны, чтобы поддержать: < /p>
(x64, arm64) с использованием msvc - linux (x64) с использованием clang
- macOS (ARM64) с использованием Clang
стратегия реализации
Я основал на этом решении. Операции в Clang < /p>
Я использую следующую настройку для конкретной платформы: < /p>
msvc (x64 /arm64) < /p>
• Тип: myint128 < /p>
• Not Worksbge :: atomic_ref < /p>
• Не работает. блокировка
clang (linux x64)
• Тип: __int128, __int64
• Механизм: std :: atomic_ref
• Примечания: работает идеально
clang (mabos). /> • Тип: __int128, __int64
• Механизм: std :: atomic
• Примечания: std :: atomic_ref недоступен на этой платформе
Я выбираю STD :: ATOMIC_REF, где возможна, потому что . /> Он работает как на тривиально-заполнимых фундаментальных типах, так и структурах. Правильный подход в целом? -Для MSVC я понимаю, что 128-битные атомные операции не являются беззакоренными, но отступление на внутренние блокировки. I Протестировал std :: atomic_ref с двумя нитями более 10 миллионов итераций, а петля CAS завершена без проблем. < /Li>
[*] Почему Std :: atomic_ref не выполняет составки на Macos arm64 (clang), хотя, хотя? - Ошибка, которую я получаю: нет шаблона с именем «atomic_ref» в пространстве имен 'std'
Мне не хватает включения? Или это известное ограничение в реализации Apple Libc ++? -Myint128-это тривиально-заполняемая 16-байтовая структура (два члена int64_t). Будут ли все атомные операции работать правильно (даже если не без блокировки)? - Я хочу избежать того, чтобы потребовать, чтобы все общие переменные в кодовой базе были объявлены как std :: atomic.instead, я хочу написать общие атомные операции, которые принимают T & и и и используют атомику внутри.
Код: Выделить всё
template
T CompareAndSwap(T& dest, T desired, T expected)
{
static_assert(std::is_trivially_copyable_v);
static_assert(sizeof(T) == 8 || sizeof(T) == 16);
#if defined(__APPLE__) && defined(__aarch64__)
std::atomic* atomicPtr = reinterpret_cast(&dest);
atomicPtr->compare_exchange_strong(expected, desired);
#else
std::atomic_ref atomicRef(dest);
atomicRef.compare_exchange_strong(expected, desired);
#endif
return expected;
}
- t = __int128 на Clang (linux, macOS)
- t = myint128 на msvc (windows)
- через множество тем, запускаемые 10 миллионов. /> Цель < /strong>
Я хочу проверить: < /p>
Это безопасно и достаточно портативно, чтобы полагаться на производство. std :: atomic_ref намеренно отсутствует в Apple Clang's Libc ++.
Подробнее здесь: https://stackoverflow.com/questions/797 ... on-clang-m
Мобильная версия