Аппаратное обеспечение принципиально отличается от доминирующих парадигм программирования тем, что все логические ворота (или схемы вообще) всегда выполняют свою работу независимо, параллельно, во все времена. Нет такой вещи, как «сделайте это, тогда сделайте это», только «сделайте это здесь, подайте результат в схему». Если на чипе есть схема с входами A и выходом B, то цепь всегда, непрерывно, обновляет B в соответствии с текущими значениями A —, независимо от того, нужен ли результат прямо сейчас «на большом снимке».
Ваш алгоритм псевдокода даже не начинает хорошо отображаться на логические ворота. Вместо этого, компаратор выглядит в Verilog (не обращая внимания, что есть встроенный ==
оператора):
assign not_equal = (a[0]^b[0]) | (a[1]^b[1]) | ...;
Где каждый XOR представляет собой отдельный логический элемент и, следовательно, работает независимо от других. Результаты «уменьшаются» логическим или, то есть выходом 1, если любой из XOR создает 1 (это также делает некоторые работы параллельно, но критический путь длиннее одного затвора).Кроме того, все эти ворота существуют в кремнии независимо от конкретных значений бит, и сигнал должен распространяться через около (1 + log w) затворы для w-разрядного целого числа. Эта задержка распространения снова не зависит от промежуточных и конечных результатов.
В некоторых семействах процессоров сравнение равенства реализуется путем вычитания двух чисел и сравнения результата с нулем (с использованием схемы, как описано выше), но применяется тот же принцип. Сумматор/вычитатель не становится медленнее или быстрее в зависимости от значений.
Не говоря уже о том, что инструкции в CPU не могут принимать меньше одного такта, так что даже если аппаратное обеспечение закончит быстрее, следующая инструкция все равно не начнется до следующего тика.
аппаратные операции могут занимать переменное время, но это потому, что они являются государственными машинами, то есть последовательной логикой. Технически можно реализовать моральный эквивалент вашего алгоритма с помощью конечного автомата, но никто этого не делает, его сложнее реализовать, чем наивная, не оптимизированная комбинаторная схема выше и менее эффективна для загрузки.
Цепи государственных машин представляют собой схемы с памятью: они сохраняют свое текущее состояние и всегда вычисляют выходы (в зависимости от текущего состояния) и следующее состояние (в зависимости от текущего состояния и входов) каждого тактового цикла. На некоторых входах они могут проходить через N состояний до тех пор, пока они не выдадут выходной сигнал, и N + x на других входах. Однако операции ALU вообще не делают этого. Трубопроводные ларьки, неверные предсказания филиалов и пропуски кеша являются общими причинами, по которым в некоторых случаях одна инструкция занимает больше времени, чем обычно. Правильно рассуждать об этом так, чтобы помочь программистам быстрее писать код сложно: вы должны учесть все хитрости и причуды реального оборудования, и их очень много. Жизненно важны эмпирические данные, то есть сравнительный анализ реального процессора черного ящика.
Обратите внимание, что даже «наивная реализация» (суммарное суммирование) занимает столько же времени, независимо от значений входов. И что такое «почти» в последнем предложении? Он принимает ровно k тактов (часто k = 1). – delnan