Восстанавливает ли прерванная транзакция xbegin контекст стека, существовавший при запуске xbegin?

Я заинтересован в инкапсуляции транзакционного xbegin и xend внутри функций XBEGIN () и XEND (), в статическом ассемблере lib. Однако мне неясно, как (или если) стек восстанавливается до исходного состояния вызова xbegin, учитывая xabort, происходящий на каком-то другом уровне стека (выше или ниже). Другими словами, является ли контекст динамического стека (включая эффекты прерываний) управляемым и откатывается как просто еще одна часть транзакции?

Этот подход на ассемблере необходим для сборки VC ++ 2010, которая не поддерживает или не поддерживает встроенные функции _xbegin () и _xend (), а сборки x64 не могут использовать вставку _asm {}.

0

Решение

связанные: см. также Описание TSX Дэвида Кантера для некоторой теории о том, как это работает под капотом и как программное обеспечение может извлечь из этого выгоду, и этот блог для некоторых экспериментальных показателей производительности на HSW (до обнаружения ошибки TSX и обновления микрокода отключали TSX на этом оборудовании.)


Intel insn ref руководство запись для xbegin довольно ясно. (См. пометьте вики ссылками на официальный PDF-файл Intel и другие материалы.)

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

Таким образом, инструкция работает как условная ветвь, где условие ветвления «произошло прерывание раньше XEND? «Например:

; NASM syntax, I assume MASM is similar
ALIGN 16
retry:
; eax holds abort info, all other architectural state + memory is unchanged
inc     [retry_count]      ; or whatever other debug instrumentation you want to add

global xbegin_wrapper_with_retry
xbegin_wrapper_with_retry:
xbegin  retry
ret

Если произойдет прерывание, это как если бы весь код, который запускался после xbegin вообще не бегал, просто перейти к резервному адресу с eax модифицирована.

Конечно, вы можете захотеть сделать что-то иное, чем просто бесконечные повторные попытки прерывания. Это не должно быть реальным примером. (Эта статья действительно есть реальный пример логики, которую вы могли бы использовать, используя встроенные функции. Похоже они просто тестируют eax вместо использования xbegin как прыжок в if, если компилятор не оптимизирует эту проверку. ИДК, если это самый эффективный способ.)

Что вы имеете в виду «прерывает эффекты»? В текущих реализациях все, что изменяет уровень привилегий (например, системный вызов или прерывание), вызывает прерывание транзакции. Таким образом, изменения уровня кольца никогда не нужно откатывать. Процессор просто прервет транзакцию, когда встретится с чем-либо, что он не может откатить. Это означает, что возможные ошибки включают в себя что-то внутри транзакции, которое всегда вызывает прерывание, но не то, что вы делаете что-то, что не может быть отменено.


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

// no idea if this is safe, or if it might get reordered by the optimizer
#define xend_MSVC  __asm _emit 0x0F  __asm _emit   0x01 __asm _emit 0xD5

Я думаю, что это все еще работает в 64-битном режиме, поскольку документ упоминает raxи похоже Заголовочный файл IACA использования __asm _emit,

Будет безопаснее поставить XEND в своей собственной функции-обертке тоже, наверное. Вам просто нужен временный интервал, пока вы не сможете перейти на компилятор со встроенными функциями, поэтому он не должен быть идеальным, пока дополнительные операции чтения / записи из ret а также call не вызывайте слишком много абортов.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]