Подтвердить что ты не робот

Производительность 32-разрядная и 64-разрядная арифметика

Являются ли родные арифметические инструкции 64 bit целыми числами медленнее, чем их счетные части 32 bit (на машине x86_64 с 64 bit OS)?

Изменить: на текущих процессорах, таких как Intel Core2 Duo, i5/i7 и т.д.

4b9b3361

Ответ 1

Это зависит от точного процессора и работы. Например, на 64-битных процессорах Pentium IV умножение 64-разрядных регистров было довольно медленным. Core 2 и более поздние процессоры были разработаны для 64-разрядной работы с нуля.

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

Структура, содержащая десятки целых чисел, будет вдвое меньше, если эти целые числа будут 32-битными, чем если бы они были 64-битными. Это означает, что для хранения будет занимать половину количества байтов, вдвое меньше места в кеше и т.д.

Используются 64-разрядные собственные регистры и арифметика, где значения могут не соответствовать 32-битным. Но основные преимущества для производительности исходят из дополнительных регистров общего назначения, доступных в наборе инструкций x86_64. И, конечно же, есть все преимущества, которые приходят из 64-битных указателей.

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

Ответ 2

Я просто наткнулся на этот вопрос, но я думаю, что здесь отсутствует один очень важный аспект: если вы действительно смотрите вниз на ассемблерный код, используя тип 'int' для индексов, скорее всего, замедлит код, создаваемый вашим компилятором. Это связано с тем, что "int" по умолчанию имеет 32-битный тип на многих 64-битных компиляторах и платформах (Visual Studio, GCC) и выполняет вычисления адресов с помощью указателей (которые обязательно являются 64-битными на 64-битной ОС), а "int" заставит компилятор испускать ненужные конверсии между 32 и 64-битными регистрами. Я только что испытал это в критическом внутреннем цикле моего кода. Переключение с "int" на "long long" в качестве индекса цикла улучшило время работы моего алгоритма примерно на 10%, что было довольно большим выигрышем, учитывая обширную векторизацию SSE/AVX2, которую я уже использовал в этой точке.

Ответ 3

В основном 32-битном приложении (имеется в виду только 32-разрядная арифметика и 32-разрядные указатели достаточны), реальными преимуществами архитектуры x86-64 являются другие "обновления" AMD, сделанные для архитектуры:

  • 16 регистров общего назначения, начиная с 8 в x86
  • Режим относительной адресации RIP
  • другие...

Это видно из нового x32 ABI, реализованного в Linux.