Можно ли «прервать» загрузку регистра из памяти вместо срабатывания страничной ошибки?

Я думаю о "Сведение к минимуму ошибок страниц (и ошибок TLB) при «перемещении» по большому графику"

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

Я хочу иметь возможность загружать некоторые данные из памяти в регистр, но иметь прерывание загрузки, а не получение ошибки страницы, если память в настоящее время выгружена. Мне нужен код для работы в пользовательском пространстве как в Windows, так и в Linux без каких-либо стандартных разрешений.

(Идеально, я также хотел бы прервать работу при ошибке TLB.)

Загрузка действительно прерывается за исключением. Затем ОС загрузит страницу и позволит вашей программе повторить загрузку. Так что это зависит от ОС. Может быть, verr (intel.com/content/dam/www/public/us/en/documents/manuals/…) проверяет, выйдет ли загрузка из строя или нет, но я не уверен в этом.

Domso 07.09.2018 14:02
verr бесполезен для этого: он проверяет только привилегии сегмента, заданные 16-битным селектором сегмента, а не адресом. Вы могли бы использовать его как mov eax, ds / verr ax, чтобы спросить, доступен ли сегмент данных для чтения. Предупреждение о спойлере: это так.
Peter Cordes 07.09.2018 20:37
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
За пределами сигналов Angular: Сигналы и пользовательские стратегии рендеринга
TL;DR: Angular Signals может облегчить отслеживание всех выражений в представлении (Component или EmbeddedView) и планирование пользовательских...
Sniper-CSS, избегайте неиспользуемых стилей
Sniper-CSS, избегайте неиспользуемых стилей
Это краткое руководство, в котором я хочу поделиться тем, как я перешел от 212 кБ CSS к 32,1 кБ (сокращение кода на 84,91%), по-прежнему используя...
1
2
213
1

Ответы 1

Часть RTM (Restricted Transactional Memory) функции TXT-NI позволяет подавлять исключения:

Any fault or trap in a transactional region that must be exposed to software will be suppressed. Transactional execution will abort and execution will transition to a non-transactional execution, as if the fault or trap had never occurred.
[...]
Synchronous exception events (#DE, #OF, #NP, #SS, #GP, #BR, #UD, #AC, #XM, #PF, #NM, #TS, #MF, #DB, #BP/INT3) that occur during transactional execution may cause an execution not to commit transactionally, and require a non-transactional execution. These events are suppressed as if they had never occurred.

Я никогда не использовал RTM, но он должен работать примерно так:

xbegin fallback

  ; Don't fault here

xend

; Somewhere else
fallback:
  ; Retry non-transactionally

Обратите внимание, что транзакция может быть прервана по многим причинам, см. Главу 16.8.3.2 тома 1 руководства Intel. Также обратите внимание, что RTM не является повсеместным.

Помимо RTM, я не могу придумать другого способа подавления нагрузки, поскольку он должен возвращать значение или, в конечном итоге, сигнализировать об условии прерывания (что было бы таким же, как #PF).

Я хочу, чтобы ОС не видела #PF, поэтому ошибка, с которой я мог справиться в пользовательском пространстве, также решит проблему.

Ian Ringrose 07.09.2018 14:11

Если бы RTM была более распространенной, это было бы отличным решением, так как это также сделало бы мою блокировку потоков пасхальной.

Ian Ringrose 07.09.2018 14:12

@IanRingrose RTM подавляет #PF, и это единственное, что я придумал. Я не могу придумать другого механизма для прерывания загрузки, архитектура x86 на самом деле не построена вокруг концепции «прерывания загрузки». Посмотрим, есть ли у кого-нибудь другие мысли :)

Margaret Bloom 07.09.2018 14:15

@IanRingrose У него все еще есть некоторые проблемы, например, не все ядра x86 поддерживают TSX. Возможно, с C++ 20 и поддержкой более высокого языка это будет более распространено. (en.cppreference.com/w/cpp/language/transactional_memory)

Domso 07.09.2018 14:18

Хорошая идея! @IanRingrose: к сожалению, нет инструкции, которая просто запрашивает TLB или текущую таблицу страниц с результатом в регистре на x86. Возможно, у какой-то другой ISA есть инструкции для этого, но я не знаю ни одной из них. В качестве дизайнерской идеи это было бы полезно только для производительности, а не для правильности, потому что всегда будет разрыв между запросом и использованием. Команда try_load insn, которая также устанавливает / очищает флаги вместо того, чтобы поднимать #PF, могла бы избежать состояния гонки, но ни одна из известных мне ISA также не имеет этого.

Peter Cordes 07.09.2018 20:11

@PeterCordes Одна проблема, чтобы быть полезной, она должна быть ОЧЕНЬ быстрой в случае, если страница находится в TLB (или в памяти).

Ian Ringrose 07.09.2018 20:24

TryLoad, который прерывается, если элемент не был в кэш-памяти ЦП (уровень 3), также был бы очень хорош ...

Ian Ringrose 07.09.2018 20:26

@IanRingrose: Быть быстрым - не проблема; Я не понимаю, почему гипотетическая инструкция queryTLB будет медленнее, чем загрузка, которая попадает в кеш L1dTLB и L1d, если страница уже горячая. Он просто запустится на порту загрузки и выдаст целочисленный результат. Порты загрузки Intel уже знают, как запускать широковещательные нагрузки, нагрузки с нулевым расширением и даже vmovddup ymm, m256 (две линейные широковещательные передачи) по какой-то причине, поэтому добавление другого типа нагрузки не кажется проблемой. То же самое для загрузки, которая устанавливает флаги в зависимости от того, прервали ли мы загрузку вместо #PF.

Peter Cordes 07.09.2018 20:32

Другие вопросы по теме