Как я могу сделать кеш-память процессора в x86 Windows?
Я заинтересован в принуждении кэш-памяти процессора в Windows (для сравнения, я хочу эмулировать запуск без данных в кэше процессора), предпочтительно базовую реализацию C или вызов Win32.
Есть ли известный способ сделать это с системным вызовом или даже с чем-то вроде sneaky, как говорят большой memcpy
?
Платформа Intel i686 (P4 и все в порядке).
Ответы
Ответ 1
К счастью, существует несколько способов явного сброса кешей.
Инструкция "wbinvd" записывает измененное содержимое кеша и помещает кеши пустым. Он выполняет цикл шины, чтобы сделать внешние кеши для очистки своих данных. К сожалению, это привилегированное обучение. Но если можно запустить тестовую программу под чем-то вроде DOS, это путь. Это имеет то преимущество, что размер кэша "OS" очень мал.
Кроме того, есть команда invd, которая делает недействительными кэширование без, сбрасывая их обратно в основную память. Это нарушает согласованность основной памяти и кеша, поэтому вам нужно позаботиться об этом самостоятельно. Не рекомендуется.
Для целей бенчмаркинга наиболее простым решением, вероятно, является копирование большого блока памяти в область, отмеченную WC (объединение записи) вместо WB. Область отображаемой памяти видеокарты является хорошим кандидатом, или вы можете пометить регион как WC самостоятельно через регистры MTRR.
Вы можете найти некоторые ресурсы по сравнению с краткосрочными подпрограммами в тестовые программы для измерения тактовых циклов и мониторинга производительности.
Ответ 2
Есть инструкции по сборке x86, чтобы заставить ЦП скрыть определенные строки кэша (например, CLFLUSH), но они довольно неясны. CLFLUSH, в частности, удаляет только выбранный адрес из кэшей L1.
что-то такое же подлый, как говорят большие воспоминания?
Да, это самый простой подход, и убедитесь, что CPU сбрасывает все уровни кеша. Просто исключите время очистки кэша от ваших benchmakrs, и вы должны получить представление о том, как ваша программа работает под давлением в кеше.
Ответ 3
К сожалению, нет способа явно очистить кеш. Некоторые из ваших вариантов:
1.) Thrash cache, делая очень большие операции с памятью между итерациями кода, который вы сравниваете.
2.) Включить кеш отключить в x86 Контрольные регистры и проверить это. Это, вероятно, также отключит кеш инструкций, что может быть не так, как вы хотите.
3.) Внесите часть кода в свой бенчмаркинг (если это возможно), используя Невременные инструкции. Хотя, это просто подсказки для процессора об использовании кеша, он по-прежнему свободен делать то, что он хочет.
1, вероятно, является самым простым и достаточным для ваших целей.
Изменить: К сожалению, я исправлен, есть инструкция по аннулированию кеша x86, см. ответ drhirsch
Ответ 4
Инструкция x86 WBINVD
запись и делает недействительными все кэши. Это описано как:
Записывает все измененные строки кэша во внутреннем кэше процессоров в основную память и делает недействительными (сбрасывает) внутренние кэши. Затем команда выдает цикл шины специальной функции, который направляет внешние кэши также записывать измененные данные, и другой цикл шины указывает, что внешние кэши должны быть признаны недействительными.
Важно отметить, что инструкция может быть выполнена только в ring0, то есть в операционной системе. Так что ваши пользовательские программы не могут просто использовать его. В Linux вы можете написать модуль ядра, который может выполнять эту инструкцию по требованию. На самом деле, кто-то уже написал такой модуль ядра: https://github.com/batmac/wbinvd
К счастью, код модуля ядра действительно крошечный, так что вы можете проверить его перед загрузкой кода из незнакомых людей из Интернета в ваше ядро. Вы можете использовать этот модуль (и запустить выполнение команды WBINVD
), прочитав /proc/wbinvd
, например, через cat/proc/wbinvd
.
Однако я обнаружил, что эта инструкция (или, по крайней мере, этот модуль ядра) действительно медленная. На моем i7-6700HQ я измерил его на 750 мкс! Это число мне кажется очень высоким, поэтому я мог ошибиться, измерив это - пожалуйста, имейте это в виду! Объяснение этой инструкции просто сказать:
Количество времени или циклов для завершения WBINVD будет зависеть от размера и других факторов разных иерархий кэша.