IO — Ivan Labs

Что происходит внутри процессора, когда вы запускаете программу

4 мин чтения
ЖелезоПроцессор

Вы дважды кликаете по значку, и через секунду программа уже работает. Вот что на самом деле происходит между этими двумя моментами, без версии из рекламного буклета про «ядра и гигагерцы».

Шаг 1: попадание программы в память

Код вашей программы хранится на диске как файл. Прежде чем процессор сможет его коснуться, операционная система загружает нужные части этого файла в оперативную память — процессор никогда не выполняет код напрямую с диска, это слишком медленно. Именно поэтому программы «загружаются» перед запуском, и именно поэтому SSD делает этот шаг быстрее, чем HDD.

Шаг 2: выборка, декодирование, выполнение

Как только код оказывается в оперативной памяти, процессор проходит по нему в цикле, который повторяется миллиарды раз в секунду:

  1. Выборка (fetch) — взять следующую инструкцию из памяти по адресу, на который указывает счётчик команд.
  2. Декодирование (decode) — понять, что эта инструкция на самом деле означает (сложить эти два числа, загрузить это значение, перейти по этому адресу).
  3. Выполнение (execute) — реально это сделать, используя внутренние исполнительные блоки процессора.
выборка → декодирование → выполнение → (повтор, следующая инструкция)

Это цикл «выборка-декодирование-выполнение», и на нём построено всё остальное в процессоре.

Шаг 3: зачем нужен кэш, а не только ОЗУ

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

Чтобы этого избежать, процессоры держат маленькие, чрезвычайно быстрые пулы памяти физически близко к исполнительным блокам — кэш, обычно разделённый на уровни L1, L2 и L3:

УровеньТипичный размерСкоростьОбщий?
L1~32–64 КБ на ядроСамый быстрыйНа каждое ядро
L2~256 КБ–2 МБ на ядроБыстрыйОбычно на каждое ядро
L3Несколько МБ – десятки МБМедленнее L1/L2, но всё ещё намного быстрее ОЗУОбщий для всех ядер

Процессор предсказывает, какие данные понадобятся дальше, и заранее держит их в кэше. Когда предсказание верно («попадание в кэш»), выполнение почти не замедляется. Когда неверно («промах кэша»), процессору приходится ждать ОЗУ — именно ту задержку, ради избежания которой и существует кэш.

Шаг 4: ядра, потоки и как делать больше одного дела

Ядро процессора может по-настоящему выполнять только один поток инструкций за раз. Многоядерные процессоры получают реальный параллелизм за счёт нескольких независимых ядер, каждое из которых крутит свой собственный цикл выборки-декодирования-выполнения. Одновременная многопоточность (то, что Intel называет Hyper-Threading) — это другое: она позволяет одному физическому ядру держать два потока инструкций и чередовать их в простаивающих исполнительных слотах — это ближе к более эффективному использованию ядром собственного простоя, чем к наличию второго ядра.

Шаг 5: почему турбочастота — не постоянная скорость

Современные процессоры указывают «турбо»-частоту, которая выше базовой. Процессор достигает этой турбочастоты лишь короткими всплесками на нескольких ядрах, ограниченный температурой и подачей питания — работа всех ядер на максимальной турбочастоте постоянно генерировала бы больше тепла, чем способно отвести большинство систем охлаждения, поэтому процессор снижает частоту, как только достигаются тепловые пределы. Это нормальное поведение, а не дефект.

Собираем всё вместе

Двойной клик по программе запускает: загрузку кода в ОЗУ → процессор выбирает инструкции по одной → кэш держит «горячие» данные под рукой → ядра (и потоки, если доступны) параллельно проходят независимые потоки инструкций → частота динамически подстраивается под нагрузку и температуру. Ничего из этого не магия — это тот же цикл выборки-декодирования-выполнения, повторённый в масштабе, который сложно интуитивно осознать, с несколькими уровнями, специально построенными, чтобы этот цикл не простаивал.

Интересно, как это применимо к конкретной проблеме производительности, с которой вы столкнулись — медленной сборке, тормозящему приложению или железу, между которым вы выбираете? Свяжитесь со мной.

Частые вопросы

Процессор выполняет всю программу сразу?

Нет. Он выполняет по одной инструкции за раз на каждое ядро, чрезвычайно быстро — современные процессоры выполняют миллиарды инструкций в секунду, а такие техники, как конвейеризация, позволяют нескольким инструкциям находиться на разных стадиях выполнения одновременно.

В чём разница между ядром и потоком?

Ядро — это физический исполнительный блок. Поток (в контексте процессора, через одновременную многопоточность вроде Hyper-Threading) позволяет одному физическому ядру жонглировать двумя потоками инструкций, заполняя простаивающие исполнительные слоты — это не то же самое, что иметь два полноценных ядра.

Почему важна оперативная память, если всю работу делает процессор?

Процессор достаточно быстр, чтобы простаивать большую часть времени в ожидании данных, если бы читал всё напрямую из ОЗУ — именно поэтому существует кэш: чтобы часто используемые данные были достаточно близко и процессор не простаивал.

Нужна помощь с этим?

Свяжитесь со мной, и я помогу разобраться.

Связаться со мной

Похожие статьи

Поделиться:X / TwitterLinkedIn