Имеет ли значение установка платформы при компиляции приложения С#?

В VS2012 (и предыдущих версиях...) вы можете указать целевую платформу при создании проекта. Я понимаю, однако, что C# "компилируется" в CIL, а затем компилируется JIT при работе в хост-системе.

Означает ли это, что единственные причины для указания целевой платформы состоят в том, чтобы преднамеренно запретить пользователям запускать программное обеспечение на определенных архитектурах или заставить приложение работать как 32-разрядное на 64-разрядной машине? Я не вижу, чтобы это было связано с оптимизацией, поскольку я предполагаю, что это происходит на этапе CIL -> Native, который происходит Just-In-Time в архитектуре хоста?

Эта ссылка MS не предложить какое-либо альтернативное объяснение, и я не могу найти никаких указаний на то, что вы должны, например, выпускать отдельные 32/64-битные версии одного и того же приложения - казалось бы логичным, что что-то, скомпилированное для "anycpu", должно работать так же хорошо и, опять же, оптимизации будут применяться на этапе JIT.


person AJ.    schedule 08.10.2012    source источник
comment
Я не знаю, изменилось ли это в VS2012, но функция редактирования и продолжения не работает при отладке приложений в 64-битном режиме в VS2010.   -  person David    schedule 09.10.2012
comment
@ Дэвис: Это не так. (но теперь вы можете использовать E&C для редактирования тел методов, содержащих анонимные методы или лямбда-выражения, за вычетом фактических операторов, в которых они появляются)   -  person Allon Guralnek    schedule 14.10.2012


Ответы (2)


Означает ли это, что единственными причинами для указания целевой платформы являются намеренное ограничение запуска программного обеспечения пользователями на определенных архитектурах или принудительное выполнение приложения как 32-разрядного на 64-разрядной машине?

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

Если ваш код на 100% управляем, то AnyCPU (или новый AnyCPU Prefer 32-Bit), скорее всего, подойдет. Оптимизация компилятора будет такой же, а JIT будет оптимизировать во время выполнения на основе текущей исполняемой платформы.

Я не могу найти намека на то, что вы должны, например, выпускать отдельные 32/64-битные версии одного и того же приложения.

Нет причин делать это, если вы не выполняете взаимодействие с неуправляемым кодом, и в этом случае потребуются отдельные 32- и 64-разрядные библиотеки DLL.

person Reed Copsey    schedule 08.10.2012
comment
Зависит ли от этого параметра P/Invoke или небезопасные вещи? (Я полагаю, что их можно считать не управляемыми на 100% ..) - person ; 08.10.2012
comment
@pst P/Invoke идет против нативного, поэтому это имеет значение (если только у вас нет способа во время выполнения убедиться, что вы используете только правильные библиотеки DLL платформы), но это не проблема оптимизации - это проблема правильности. - person Reed Copsey; 08.10.2012
comment
@pst - Да. Потому что установка этого флага платформы (если он используется в исполняемом файле записи, отвечающем за запуск среды выполнения) приведет к загрузке кода в 32- или 64-битное пространство памяти. Если ваш p/invoke написан так, чтобы указатели и другие типы памяти были 32-битными, и он загружается в 64-битную среду выполнения (или наоборот), ничего не получится. - person Adam; 08.10.2012
comment
У меня есть еще одна веская (хотя и незначительная) причина, почему вы хотите ограничить платформу. В некоторых сценариях потребление памяти можно уменьшить, работая в 32-разрядном режиме по сравнению с 64-разрядным, поскольку все ссылки на объекты имеют размер всего 4 байта вместо 8. Принудительное использование 32-разрядного режима может уменьшить объем памяти программы, если вы знаете, что никогда не будете потребляют более 2 Гб. - person Allon Guralnek; 08.10.2012
comment
@AllonGuralnek Да, в общем, если вам не нужна 64-битная версия, 32-битная лучше. Я считаю, что это часть того, почему по умолчанию в VS 2012 теперь используется AnyCPU Prefer 32-bit вместо AnyCPU. - person Reed Copsey; 08.10.2012
comment
@Reed: Ха, я впервые слышу об этом новом варианте AnyCPU. Я думаю, что его следовало назвать просто 32-разрядным, потому что согласно эту статью, она всегда будет работать только как 32-разрядная версия. Или, возможно, он будет работать как 64-битный на Itanium (но кого это волнует)? - person Allon Guralnek; 09.10.2012
comment
Отличный ответ и комментарии, спасибо. @Allon Guralnek: в моем случае потребление памяти не является проблемой, поскольку я склонен работать только на машинах с 8 ГБ ОЗУ, но я думаю, если бы я выпустил это более широко, в том числе для людей, работающих на 32-битных машинах (отсюда и вопрос) , это может быть проблемой. Интересно, насколько это компромисс? Предположительно, запуск 32-битного JIT-кода на 64-битной машине под управлением 64-битной Windows также подразумевает WOW64 и дополнительные изменения режима ЦП с режима Long на режим совместимости? - person AJ.; 10.10.2012
comment
@AJ: На самом деле, работа в 32-битном режиме в 64-битной Windows может привести к повышению производительности. WOW64 настолько тонкий, что не влияет на производительность, но снижение использования памяти 32-разрядным приложением означает, что больше может поместиться в кеш ЦП (и другие кеши), а памяти требуется меньше времени для выделения, чтения и записи. Этот прирост производительности может быть заметным (или даже значительным) для определенных типов приложений. Недостатков нет, поэтому вам всегда следует предотвращать запуск ваших приложений в 64-разрядном режиме, если вы не подозреваете, что собираетесь исчерпать адресное пространство в 2 ГБ. - person Allon Guralnek; 11.10.2012

У Рида есть хороший ответ здесь. Тем не менее, я думаю, также важно отметить, что этот параметр является просто флагом в DLL - он практически не имеет никакого эффекта в большинстве ситуаций. Загрузчик среды выполнения (часть собственного кода, запускающая среду выполнения .NET) отвечает за просмотр этого флага и указание запуска соответствующей версии среды выполнения .NET.

Из-за этого флаг будет иметь значение только тогда, когда он установлен в EXE-файле, и не будет иметь никакого эффекта, если он установлен в DLL. Например, если у вас есть «32-разрядная .NET DLL», которая используется либо 64-разрядным .NET EXE, либо .NET EXE с любым процессором, и вы запускаете EXE на 64-битная машина - тогда загрузчик запустит 64-битную среду выполнения. Когда приходит время загрузить 32-битную DLL, уже слишком поздно - 64-битная среда выполнения уже выбрана, поэтому ваша программа завершится ошибкой (я полагаю, что вы получите исключение BadImageFormatException).

person Adam    schedule 08.10.2012
comment
+1 Очень хорошее дополнение к ответу Рида. И да, вы правы насчет ошибки BadImageFormatException. - person Icarus; 08.10.2012