При переходе по маршруту взаимосвязанной работы в фиктивном местоположении необходимо учитывать несколько моментов:
- Находясь в L1d этого ядра,
- Не используется другими ядрами
- Не создавать длинные цепочки зависимостей
- Избегайте задержек из-за пропуска переадресации магазина
Без контекста все является лишь предположением, поэтому цель состоит в том, чтобы сделать наилучшее предположение.
Место в верхней части стопки - хорошее предположение для 1 и 2.
Преднамеренно назначенная переменная стека, скорее всего, исправит 3, а поскольку других хранилищ в полете нет, 4 не проблема. Лучшая операция выглядит как lock not
.
Для того, чтобы не выделять переменную стека, необходимо, чтобы операция не выполнялась, поэтому lock or [mem], 0
- хороший вариант. Операнд должен быть байтовым, чтобы избежать проблем с 4. Для 3 это всегда предположение. (Хотя можно было использовать обратный адрес, сборка без контекста не знает этого. Но MSVC _AddressOfReturnAddress
может быть хорошей идеей)
Я читал про красную зону. Отсутствие его в Windows дает возможность дополнительной оптимизации.
lock not byte ptr [esp-1]
без дополнительной переменной подходит для Windows, так как данные считаются непостоянными и не должны использоваться. Нет проливных регистров, поэтому нет зависимости от ложных данных.
ABI с 128-байтовой красной зоной исключает использование lock not byte ptr [esp-1]
. 128 байтов вне стека, вероятно, не будут L1d. Тем не менее, поскольку красная зона вряд ли будет использоваться в качестве обычного стека, ответ, данный @Peter Cordes, выглядит хорошо.
TSX в первую очередь вызывает сомнения из-за его отсутствия (не поддерживается на данном ЦП или отключен в результате исправления ошибок или снижения безопасности). В обозримом будущем будет существовать только RTM (Исчезла ли Hardware Lock Elision навсегда из-за Spectre Mitigation?). Согласно Обзор RTM, пустая транзакция RTM все еще является забором, поэтому ее можно использовать.
Успешно зафиксированная область RTM, состоящая из XBEGIN, за которым следует XEND, даже без операций с памятью в области RTM, имеет ту же семантику упорядочения, что и инструкция с префиксом LOCK.
Остерегайтесь неудачных транзакций или неподдерживаемой RTM. Псевдокод выглядит следующим образом:
if (rtm_supported && _xbegin() == 0xFFFFFFFF)
_xend();
else
dummy_interlocked_op();
person
Alex Guteniev
schedule
13.06.2020