По какой причине я бы выбрал параметр выравнивания файла компилятора C #, отличный от 512? - PullRequest
42 голосов
/ 05 марта 2011

В MSDN я вижу, как изменить выравнивание файлов для компиляции C # (через настройки проекта и командную строку).

Я гуглил и видел статьи, объясняющие, что выравнивание файла на 512 байт уменьшает размер .dll. Я проверил себя с разными выравниваниями файлов и увидел, что да, это так.

Мой вопрос:

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

Кроме того, что именно это делает? Страницы MSDN говорят о разделах? Что такое разделы?

http://msdn.microsoft.com/en-us/library/0s4tzdf2.aspx

1 Ответ

68 голосов
/ 05 марта 2011

Это довольно техническая деталь реализации. Для начала вам необходимо понять структуру файла PE32, формат файла для DLL и EXE в Windows. Канонической статьей для этого является статья Мэтта Петрика «Вглядываясь в PE, обзор формата переносимых исполняемых файлов Win32». Написан 17 лет назад, но все еще актуален и доступен .

Параметр / filealign ссылается на значение поля IMAGE_OPTIONAL_HEADER.FileAlignment. Он определяет, как исходные данные в разделе выровнены. Раздел - это кусок кода или данных в файле. Почти исключительно данные в случае чистых сборок .NET.

Существует очень тесная связь между форматом файла и диском. Исполняемый образ используется в качестве резервного файла для отображения в памяти файла в Windows. Исполняемые файлы загружаются путем сопоставления файла с адресным пространством виртуальной памяти. Очень эффективно, загрузка DLL включает в себя только создание этого отображения, никакие реальные данные не читаются из файла. Это происходит лениво, когда процесс пытается прочитать байт из раздела. Если он еще не загружен в память, это вызывает ошибку страницы, и операционная система считывает 4096 байт из файла в память. Большим преимуществом является то, что вы не платите за данные или код, который не используете. Также причина в том, что чтение [атрибутов] стоит дорого, когда вы читаете его в первый раз.

Важность выравнивания файлов заключается в том, как выстраиваются необработанные данные в разделах. Большинство современных исполняемых файлов, которые содержат машинный код, используют выравнивание размером 4096 байт, размер страницы виртуальной памяти. Это не очень актуально для сборок, содержащих управляемый код, IL - это просто данные. Что имеет смысл использовать меньшее выравнивание, которое тратит меньше места. 512 байт (не килобайт) - это счастливое число, это наименьшее допустимое значение в формате PE32.

Единственная возможная причина, по которой я вообще могу добавить эту опцию в пользовательский интерфейс, заключается в том, что компилятор C # имеет очень мало опций компиляции по сравнению с другими компиляторами. «Другие» - это компиляторы, которые генерируют нативный код. Так что опция есть, потому что опция есть у компилятора. Многие изменения покрыты [атрибутами], что делает командную строку компилятора короткой и быстрой. Но нет атрибута для выравнивания файла, его нужно знать перед созданием файла, атрибут будет слишком поздно.

Противоположный пример - компилятор и компоновщик C ++, в среде IDE для их установки предлагается девятнадцать страниц свойств. Но все же, не охватывая их всех, по-настоящему непонятные должны быть установлены на странице параметров «Командная строка».

...