Почему побитовые операции были немного быстрее, чем операции сложения/вычитания на старых микропроцессорах?

сегодня я наткнулся на этот отрывок:

на большинств более старых микропроцессорах, побитовые деятельности немножко более быстры чем добавление и операций вычитания и, как правило, значительно быстрее, чем умножение и деление оперативный. В современных архитектурах это не так: побитовые операции обычно являются та же скорость, что и сложение (хотя все еще быстрее, чем умножение).

мне интересно, почему побитовые операции были немного быстрее, чем операции сложения/вычитания на старых микропроцессоров.

все, что я могу придумать, это вызвать задержку в том, что схемы для реализации сложения/вычитания зависят от нескольких уровней логических элементов (параллельных сумматоров и прочего), в то время как побитовые операции имеют гораздо более простые реализации схемы. Это причина?

Я знаю арифметические и побитовые операции, выполняемые в течение одного тактового цикла на современных процессорах, но говоря чисто о времени распространения для схемы, задержка все еще теоретически существует в современных процессорах?

наконец, у меня был концептуальный вопрос C о выполнении операции побитового сдвига:

unsigned x = 1;
x <<= 5;

unsigned y = 0;
y += 32;

и x и y должно содержать значение 32, но это заняло 5 отдельные левые смены, чтобы получить x к этому значению (как в битовых сдвигах, реализованных через трубы)? Чтобы уточнить, я спрашиваю исключительно о поведении схемы, а не о количество тактов.

6 ответов


в любой двоичной побитовой операции каждый выходной бит зависит только от двух соответствующих битов на входах. В операции add каждый выходной бит зависит от соответствующих битов на входах и всех битов справа (в сторону более низких значений).

например, самый левый бит 01111111 + 00000001 равен 1, но самый левый бит 01111110 + 00000001 равен 0.

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

есть способы ускорить это, подав несколько входных битов в более сложные логические схемы. Но это, конечно, требует больше площади в чипе и больше сила.

сегодняшние процессоры имеют много различных блоков для выполнения различных видов рабочих нагрузок, магазинов, сложения, умножения, операций с плавающей запятой и многое другое. Учитывая сегодняшние возможности, работа над add невелика по сравнению с другими задачами, поэтому она вписывается в один процессорный цикл.

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


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

таким образом, вы в конечном итоге наивное решение N раз Полные Сумматоры где N-сколько битов в ширину ваш ALU.

эти надоедливые несет означает, что у вас есть много задержки propogation. И, поскольку один унос может сделать весь результат неточным, вам в конечном итоге придется ждать довольно значительное количество времени для всех значения переноса и, в свою очередь, все остальные полные сумматоры вниз по цепочке для сопоставления.

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

Если вы хотите более подробную информацию, вы, вероятно, нужно спросить на http://electronics.stackexchange.com вместо


чтобы ответить на ваш последний вопрос, это зависит. Некоторые архитектуры имеют сдвиги только на 1 (например, z80), некоторые архитектуры предоставляют сдвиги большими константами и/или переменными, но реализовать их внутренне как куча "сдвига на 1" (например, старые реализации x86), есть некоторые архитектуры, которые могут сдвигаться более чем на 1 за один цикл, но только если сумма сдвига является константой, есть некоторые архитектуры (например, современные реализации x86), которые используют бочка перевертыш и может перейти к переменной в одном цикле, и есть еще больше возможностей.

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


некоторые реализации добавления должны сделать дополнительный цикл для бита переноса. Например: 16-битное целое число требует нескольких инструкций на 8-битном процессоре. Это также относится и к смене. Но сдвиг всегда может сдвигать биты высоты на более низкие биты следующего байта. Добавление должно добавить Нижний бит в дополнительный раунд.


бит мудрый оператор выполняется за меньшее время, потому что

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

вот почему смещение битов быстрее, чем другие арифметические операции


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

предположительно, кто-то может ответить более точно и тщательно.