Прошить iCache в x86 - PullRequest
       23

Прошить iCache в x86

1 голос
/ 21 октября 2011

Можно ли как-то сбросить iCache в архитектуре x86?Как и WBINVD, который делает недействительными и сбрасывает все строки кэша в кэше данных.

1 Ответ

2 голосов
/ 14 февраля 2019

Согласно документам, wbinvd сбрасывает и делает недействительными все кэши , а не только данные и унифицированные кэши. (Я не уверен, включает ли это TLB, если вы запустили его с включенной подкачкой.)


Что вы пытаетесь проверить? L1i Miss / L2 хит для выборки кода? Я не думаю, что возможно преднамеренно очистить просто I-кеш, без очистки всех уровней кеша.

Вы можете создать пропущенные конфликты для конкретной строки, выполнив код по 8 адресам, которые ее называют, предполагая 8-канальный 32-килобайтный кэш L1i. Но замена кеша, как правило, псевдо-LRU, а не истинная LRU, поэтому вам может потребоваться несколько раз перепрыгнуть через набор из более чем 8 строк псевдонимов.


clflush / clflushopt должны выполнить трюк для конкретной строки кэша . Они должны очистить строку от всех уровней кэша во всех ядрах.

Я предполагаю, что они также будут извлекать декодированные мопы из (виртуально адресуемого) кеша мопов.

Инструкция CLFLUSH может использоваться на всех уровнях привилегий и подвергается всем проверкам разрешений и сбоям, связанным с загрузкой байтов (и, кроме того, , кроме того, команде CLFLUSH разрешено сбрасывать линейный адрес только для выполнения сегмент ). Как и загрузка, инструкция CLFLUSH устанавливает бит A, но не бит D в таблицах страниц.


Но если вам нужна эта корректность после JIT-компиляции чего-либо , достаточно просто перейти к новым написанным инструкциям или вызвать их, чтобы избежать устаревшей выборки команд.

(На самом деле, в текущих реализациях x86 они отслеживают хранилища по любому адресу кода в конвейере, поэтому вы никогда не увидите устаревшую выборку команд, даже если у вас одна и та же физическая страница сопоставлена ​​с разными виртуальными адресами, и вы пишете один раз выполнение другого. Наблюдение за извлечением устаревших инструкций на x86 с самоизменяющимся кодом )


Вам нужно только заботиться о том, чтобы ваш компилятор оптимизировал «мертвые хранилища» для буфера, который вы приводите к указателю на функцию. В GNU C / C ++ используйте __builtin___clear_cache в диапазоне записанных вами байтов. Он компилируется в ноль инструкций на x86 (в отличие от ARM или других ISA с некогерентными кэшами инструкций), но все равно необходимо не оптимизировать хранение байтов инструкций: Как работает __builtin___clear_cache?

...