Сравнение производительности x64 и x86 .Net

Я пытаюсь понять, какие различия в производительности существуют при запуске собственного приложения C#/.Net 4.0 в x64 и x86. Я понимаю соображения памяти (x64 адресует всю память, x86 ограничена 2/4 ГБ), а также тот факт, что приложение x64 будет использовать больше памяти (все указатели имеют 8 байтов вместо 4 байтов). Насколько я могу судить, ничто из этого не должно влиять ни на какие инструкции часов для часов, поскольку конвейер x64 достаточно широк, чтобы обрабатывать более широкие инструкции.

Есть ли падение производительности при переключении контекста из-за большего размера стека для каждого потока? Какие соображения производительности мне не хватает при оценке двух?


person Superman    schedule 28.06.2011    source источник
comment
Вы сравнивали оба варианта или это мысленный эксперимент? Если вы проводили бенчмаркинг, каковы были результаты?   -  person Richard Pennington    schedule 29.06.2011


Ответы (2)


Джо Уайт привел несколько веских причин, по которым ваше приложение может работать медленнее. Большие указатели (и, следовательно, более крупные ссылки в .NET) будут занимать больше места в памяти, а это означает, что меньше вашего кода и данных будет помещаться в кеш.

Однако существует множество полезных причин, по которым вы можете захотеть использовать x64:

  • Соглашение о вызовах AMD64 используется по умолчанию в x64 и может быть немного быстрее, чем стандартные cdecl или stdcall, при этом многие аргументы передаются в регистрах и используются регистры XMM для операций с плавающей запятой.

  • CLR будет выдавать скалярные инструкции SSE для работы с операциями с плавающей запятой в 64-разрядной среде. В x86 он возвращается к использованию стандартного стека x87 FP, который немного медленнее, особенно для таких вещей, как преобразование между целыми числами и числами с плавающей запятой.

  • Наличие большего количества регистров означает гораздо меньшую вероятность того, что JIT придется их пролить из-за давления на регистры. Переполнение регистров может быть довольно дорогостоящим для быстрых внутренних циклов, особенно если функция встраивается и вводит там дополнительное давление на регистры.

  • Любые операции с 64-битными целыми числами могут принести огромную пользу, поскольку они могут помещаться в один регистр, а не разбиваться на две отдельные половины.

  • Это может быть очевидно, но дополнительная память, к которой может получить доступ ваш процесс, может быть весьма полезной, если ваше приложение интенсивно использует память, даже если оно не достигает теоретического предела. Фрагментация может привести к тому, что вы столкнетесь с условиями «недостаточно памяти» задолго до того, как вы достигнете этой отметки.

  • Относительная RIP-адресация в x64 может в некоторых случаях уменьшить размер исполняемого образа. Хотя это не относится непосредственно к приложениям .NET, это может повлиять на совместное использование библиотек DLL, которые в противном случае пришлось бы перемещать. Мне было бы интересно узнать, есть ли у кого-нибудь конкретная информация по этому поводу в отношении .NET и управляемых приложений.

Помимо этого, x64-версия среды выполнения .NET, по крайней мере, в текущих версиях, выполняет больше оптимизаций, чем эквивалент x86. Такие вещи, как встраивание и выравнивание памяти, кажется, происходят гораздо чаще. Фактически, некоторое время назад была ошибка, которая препятствовала встраиванию любого метода, который принимал или возвращал тип значения; Я помню, как это было исправлено в версии x64, а не в версии x86.

На самом деле, единственный способ определить, что лучше для вашего приложения, — это профилировать и тестировать обе архитектуры и сравнивать реальные результаты. Тем не менее, я лично просто использую Any CPU везде, где это возможно, и избегаю всего, что по своей сути зависит от архитектуры. Это упрощает сборку и развертывание и, как мы надеемся, станет более надежным в будущем, когда большинство пользователей перейдут исключительно на x64.

person MikeP    schedule 28.06.2011
comment
Количество регистров ничего не меняет, в современных ЦП, так как ассемблерный код транслируется в микрооперации. x64 в коде общего назначения имеет тенденцию быть медленнее, чем x86, при работе с целыми числами и памятью. С другой стороны, SSE2 FPU быстрее, чем x87. Но, как всегда, гораздо быстрее может измениться используемый алгоритм (например, использовать кеш или таблицы поиска), а не целевой процессор. - person Arnaud Bouchez; 09.03.2013
comment
Наличие большего количества регистров в вашем распоряжении наверняка изменит ситуацию. Даже с переименованием регистров, которое выполняют процессоры x86, он ничего не может сделать с явными зависимостями, которые компилятор вынужден создавать из-за ограниченного набора регистров. Кроме того, этот вопрос не касался изменения алгоритма, поэтому никто не удосужился упомянуть об этом. - person MikeP; 10.03.2013

Тесно связанный с «x64-приложением будет использовать больше памяти» тот факт, что с 64-битным приложением ваша локальность ссылки меньше (поскольку все размеры ваших указателей удваиваются), поэтому вы получаете меньше пробега от ЦП. бортовой (сверхбыстрый) кеш. Вы должны чаще извлекать данные из системной оперативной памяти, которая намного медленнее, чем кэш L2 и даже L1 на кристалле.

person Joe White    schedule 28.06.2011