x86_64 - производительность самоизменяющегося кода

Я читаю документацию по архитектуре Intel, том 3, раздел 8.1.3;

Самомодифицирующийся код будет выполняться с более низким уровнем производительности, чем немодифицирующийся или обычный код. Степень ухудшения производительности будет зависеть от частоты модификации и конкретных характеристик кода.

Итак, если я уважаю правила:

(* ОПЦИЯ 1 *) Сохранение измененного кода (как данных) в сегменте кода; Перейти к новому коду или промежуточному месту; Выполнить новый код;

(* ВАРИАНТ 2 ) Хранить измененный код (как данные) в сегменте кода; Выполнить инструкцию по сериализации; ( Например, инструкция CPUID *) Выполнить новый код;

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

Правильно ли мое понимание?

2 ответа

Решение

Существует разница между кодом, который просто еще не кэширован, и кодом, который модифицирует инструкции, которые уже спекулятивно находятся в полете (извлекаются, могут быть декодированы, возможно, даже находятся в буфере планировщика и переупорядочиваются в ядре вне порядка), Записывает в память, которая уже просматривается, поскольку инструкции процессора заставляют его работать очень медленно. Это то, что обычно подразумевается под самоизменяющимся кодом. Избежать этого замедления, даже когда JIT-компиляция не слишком сложна. Просто не переходите в свой буфер, пока все не будет написано.

Изменение один раз в неделю означает, что вы можете получать штраф в одну микросекунду один раз в неделю, если вы делаете это неправильно. Это правда, что часто используемые данные с меньшей вероятностью будут извлечены из кэша (поэтому чтение чего-либо несколько раз с большей вероятностью приведет к "зависанию"), но конвейерная очистка с самоизменяющимся кодом должна применяться только в самом первом случае. время, если вы столкнетесь с этим вообще. После этого выполняемые строки кэша находятся в пробе. все еще горячий в I-кеше L1 (и кеше UOP), если 2-й запуск происходит без большого количества промежуточного кода. В D-кеше L1 он еще не изменен.

Я забыл, если http://agner.org/optimize/ говорит о самомодифицирующемся коде и JIT. Даже если нет, вам следует прочитать руководства Агнера, если вы пишете что-либо в ASM. Некоторые вещи в основном "оптимизирующем асме" устарели и не очень актуальны для Sandybridge и более поздних процессоров Intel. Проблемы с выравниванием / декодированием менее важны благодаря кэш-памяти uop, а проблемы выравнивания могут быть разными для микроархивов семейства SnB.

"В следующий раз", вероятно, не так; Алгоритмы кэширования учитывают доступы, выходящие за рамки первого (не делать этого было бы довольно наивно). Однако вскоре после первых нескольких посещений штраф должен быть отменен. ("Мало" может быть две или тысячи, но для компьютера даже миллион - ничто.)

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

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