Согласно документам, 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?