2

В книге Linkers and Loaders упоминается, что одна из причин, по которой исполняемые файлы имеют отдельный раздел кода, состоит в том, что раздел кода может храниться на страницах только для чтения, что приводит к увеличению производительности. Это все еще верно для современной ОС? Видя, как Just in Time compilers генерируют код «на лету», я полагаю, им нужны перезаписываемые страницы. Означает ли это, что сгенерированный код JIT всегда будет сравниваться с производительностью? Если да, то насколько значителен этот хит?Ухудшается ли производительность JIT в связи с доступными для записи страницами?

ответ

1

Эффекты управления памятью в сторону (что объясняется в других ответах), ЦП не нуждается в постоянной проверке, если текущий поток инструкций изменен, а промежуточные результаты в конвейере должны быть выброшены, а новый код должен читать. В случае компиляции jit этот сценарий может часто возникать в зависимости от конструкции компилятора, глубины конвейера CPU, размера кеша кода процессора и количества других процессоров, которые могут модифицировать этот код. Обычно это не допускается в хорошо спроектированных современных системах, где код генерируется на записываемую страницу и помечен как исполняемый и readonly впоследствии. Конечно, это не уникально для jit. Это может произойти во всех видах саморедактирующего кода.

+0

К сожалению, я не думал об изменении страницы для чтения только во время выполнения. Как вы обычно это делаете? Я не помню, чтобы увидеть системные вызовы специально для Linux. –

+0

Я уверен, что .NET отмечает страницы как R/O, если только по соображениям безопасности. –

+0

Системный вызов является mprotect и является частью POSIX. –

1

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

1

Увеличение производительности происходит не из-за того, что страницы прочитаны только или нет. Преимущество состоит в том, что страницы, доступные только для чтения, могут совместно использоваться между процессами, поэтому вы используете меньше памяти, что означает меньшую замену (как в кешках L1/L2/L3, так и на диске в крайних случаях).

JIT пытается смягчить это без необходимости JITting, но только JIT для горячих функций. Это приведет лишь к небольшому увеличению объема памяти, поскольку количество горячих функций относительно невелико.

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

+0

. NET, с NGEN. –