Регистры, счётчики и тактовый сигнал
Урок собирает из триггеров многобитные блоки — регистры и счётчики — и объясняет роль тактовой частоты.
Регистр — группа триггеров, хранящая многобитное значение (например, 32 или 64 бита). Счётчик — регистр, увеличивающий своё значение на каждом такте.
Зачем регистры
Регистры — самая быстрая память процессора, прямо «под рукой» у АЛУ. В них лежат операнды текущих вычислений, адреса, промежуточные результаты. n-битный регистр — это просто n D-триггеров, тактируемых общим сигналом: по фронту все они одновременно защёлкивают новое значение. Поэтому регистр обновляется целиком за один такт.
Регистр и счётчик в коде
class Register:
def __init__(self, width=8):
self.width = width
self.value = 0
def load(self, v): # защёлкнуть новое значение по такту
self.value = v & ((1 << self.width) - 1)
def __str__(self):
return format(self.value, f"0{self.width}b")
class Counter(Register):
def tick(self): # +1 каждый такт, с переполнением
self.load(self.value + 1)
reg = Register(8); reg.load(0b1010)
print("регистр загружен:", reg)
cnt = Counter(4)
print("счётчик по тактам:")
for _ in range(6):
cnt.tick()
print(" ", cnt, "=", cnt.value)Вывод:
регистр загружен: 00001010 счётчик по тактам: 0001 = 1 0010 = 2 0011 = 3 0100 = 4 0101 = 5 0110 = 6
Как работает под капотом: тактовый сигнал
Тактовый сигнал (clock) — это «метроном» процессора: прямоугольный сигнал, который тикает миллиарды раз в секунду. На каждый фронт вся синхронная логика делает один шаг. Тактовая частота 3 ГГц означает 3 миллиарда тактов в секунду, то есть один такт длится примерно 0,33 наносекунды.
такт: ┌──┐ ┌──┐ ┌──┐ ┌──┐
│ │ │ │ │ │ │ │
───┘ └──┘ └──┘ └──┘ └───
↑ ↑ ↑ ↑
фронт фронт фронт фронт
(на каждом фронте регистры защёлкивают новое значение)
период T = 1 / частота
3 ГГц -> T ≈ 0.33 нс
Почему частоту нельзя повышать бесконечно? За один такт сигнал должен успеть пройти сквозь самую длинную цепочку вентилей между двумя регистрами (критический путь) и устаканиться. Если такт короче этой задержки — данные «не доедут», возникнут ошибки. Плюс выше частота — больше тепла. Отсюда современный предел в единицы гигагерц.
Посчитаем максимальную частоту
def max_frequency(critical_path_ns):
# минимальный период = задержка критического пути
period_s = critical_path_ns * 1e-9
freq_hz = 1 / period_s
return freq_hz / 1e9 # в ГГц
for delay in (0.5, 0.33, 0.25):
print(f"критический путь {delay} нс -> максимум {max_frequency(delay):.2f} ГГц")Вывод:
критический путь 0.5 нс -> максимум 2.00 ГГц критический путь 0.33 нс -> максимум 3.03 ГГц критический путь 0.25 нс -> максимум 4.00 ГГц
Глубже в тему
Полезно увидеть регистр не как отдельную сущность, а как просто «шину триггеров». 32-битный регистр — это 32 D-триггера, у которых тактовый вход общий, а входы и выходы данных идут параллельно. По одному фронту все 32 бита защёлкиваются одновременно — вот почему регистр обновляется целиком и атомарно: не бывает состояния, когда половина битов уже новая, а половина ещё старая. Эта атомарность — фундамент того, что процессор можно считать пошаговой машиной. Регистры — вершина иерархии памяти: они быстрее кэша и оперативной памяти именно потому, что физически расположены вплотную к АЛУ, и сигналу не нужно ехать через длинные шины. Платой за скорость становится их малое число, о чём подробнее пойдёт речь в разделе про устройство процессора.
Счётчик добавляет к регистру ровно одну деталь — сумматор, который каждый такт прибавляет единицу к собственному значению регистра и кладёт результат обратно. Так из «памяти» получается «память, которая сама движется во времени». Этот же приём лежит в основе важнейшего регистра процессора — счётчика команд (PC): после выборки команды он инкрементируется и указывает на следующую. Счётчики вообще вездесущи: они отсчитывают такты для таймеров, формируют адреса при переборе массива, делят частоту. По сути, любой циклический процесс в железе так или иначе опирается на счётчик.
Тактовый сигнал — это «метроном» всей синхронной логики, и стоит прочувствовать масштаб его темпа. Частота 3 ГГц означает три миллиарда фронтов в секунду, то есть один такт длится около 0,33 наносекунды. За это время свет проходит всего около десяти сантиметров — поэтому на таких частотах даже длина проводников на кристалле перестаёт быть пренебрежимой. На каждый фронт вся синхронная логика делает ровно один шаг, и именно поэтому мы можем рассуждать о процессоре как о машине, выполняющей действия дискретными ударами часов, а не непрерывно.
Почему частоту нельзя поднимать бесконечно — ключевой вопрос всей цифровой техники. За один такт сигнал обязан успеть пройти сквозь самую длинную цепочку логики между двумя соседними регистрами (это и есть критический путь) и устаканиться до прихода следующего фронта. Если такт короче этой задержки, новое значение «не доедет» до триггера вовремя, и он защёлкнет мусор — возникнут ошибки. Отсюда строгая формула: максимальная частота равна единице, делённой на задержку критического пути. Второй ограничитель — тепло: мощность растёт примерно пропорционально частоте (а с учётом необходимого роста напряжения — ещё быстрее), и около середины 2000-х индустрия упёрлась в «потолок частот». Именно поэтому дальнейший рост производительности пошёл не через гигагерцы, а через многоядерность и увеличение числа команд за такт (IPC); процессор на 2 ГГц с высоким IPC вполне может обгонять процессор на 3 ГГц.
Частые ошибки
- Думать, что больше ГГц всегда быстрее. Производительность зависит ещё от числа команд за такт (IPC); процессор на 2 ГГц может обгонять 3 ГГц.
- Игнорировать критический путь. Частоту ограничивает самая медленная цепочка логики между регистрами.
- Считать, что регистр обновляется «постепенно». Все его триггеры защёлкиваются одновременно по фронту такта.
Итог
- Регистр — n триггеров с общим тактом; самая быстрая память процессора.
- Счётчик — регистр, инкрементируемый каждый такт.
- Тактовая частота ограничена задержкой критического пути и тепловыделением.