Насколько надежно отслеживание записи страниц в Windows с учетом кэшей процессора - PullRequest
12 голосов
/ 27 июня 2019

Всегда ли ::GetWriteWatch предоставляет обновленный список измененных страниц?Или, возможно, из-за кэшей процессора некоторые страницы по-прежнему считаются неизмененными, поскольку кэшированные записи не были сброшены в основную память?


Рассмотрим следующий фрагмент кода C ++:

auto ptr = ::VirtualAlloc(NULL, 8192, MEM_COMMIT | MEM_RESERVE, MEM_WRITE_WATCH);
auto num = new (ptr) int{};
::ResetWriteWatch(ptr, 8192);

// ... calculations that involve writing to 'num' ...

::GetWriteWatch(/* ... */);

Это должно зарезервировать и зафиксировать две страницы виртуальной памяти, изменить первую страницу и, наконец, запросить все измененные страницы.

Гарантируется ли, что первая страница будет указана как измененная при вызове ::GetWriteWatch * * 1013

Ответы [ 2 ]

8 голосов
/ 03 июля 2019

тупой ответ: предполагается Да .

Хотя документация не дает явной гарантии, ее можно предположить, поскольку она касается MMU и ЦП, а также управления памятью низкого уровня. Это работает как остальная часть API: см. создание защитных страниц и т. Д. В совокупности все эти функции защиты и защиты API не будут наполовину столь же полезными, как они действительны, если вы не можете рассчитывать на они точны вплоть до инструкции, вызывающей ошибку. Это, как говорится, то, как это на самом деле достигается OS / CPU / MMU / TLB / CACHE, для меня немного неясно, обновлюсь, если я это выясню.

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

7 голосов
/ 01 июля 2019

Не случайно часы записи работают с гранулярностью страниц.Это потому, что это обрабатывается на уровне процессора через таблицу страниц для MMU.Я не могу найти авторитетный источник, но я понимаю, что это работает через атрибут страницы только для чтения.Просматриваемая страница доступна только для чтения, но ошибка программной страницы при записи обрабатывается путем добавления просматриваемой страницы в измененный список.

Таким образом, устаревшие данные в кэшах процессора не имеют значения.Это обрабатывается на уровне MMU, и MMU в любом случае тесно связан с кэшем.

Я бы больше беспокоился о состоянии гонки, потому что они появляются на уровне C ++.Запись на просматриваемую страницу может происходить из другого потока, даже когда GetWriteWatch работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...