CPU, Memory Models, Concurrency, Multiprocess, Multithreading и Async. Часть 2
Продолжаем разбираться с процессорами а именно с тем как развивалась их конфигурация со временем.
В прошлом посте упомянули что у CPU есть важная характеристика - тактовая частота, по сути мощность устройства, чем она выше тем быстрее выполнится наша программа. Казалось бы - давайте повышать тактовую частоту и увеличивать мощности? И это бы работало если бы повышение тактовой частоты не приводило к:
- повышению напряжения
- изменению в дизайне самого устройства
- изменению схемы охлаждения
Поэтому основной фокус в создании микросхем для массового потребителя был направлен на то чтобы дать больше мощности за счет добавления дополнительных ядер к процессору. Каждое ядро имеет свою тактовую частоту и можем выполнять команды независимо от других ядер (особенно быстро будет работать если у выполняющихся программ нет никакой общей памяти). И имя этому подходу - Симметричная многопроцессорность (SMP).
За счет такого маневра мы можем в теории можем исполнять инструкций в секунду в N раз больше чем на аналогичном процессоре с одним ядром. Но это лишь теория, на практике достичь этого невозможно в силу архитектурных ограничений (если получится обсудим это отдельно).
Но есть ли лимиты у подобного способа масштабирования? Теоретически нет. А практически как и всегда нужно помнить о том что чип будет увеличиваться в размерах, нужно его охлаждать и следить за энергопотреблением.
Перейдем к ОС и Софту.
Мультизадачные ОС создавались с учетом новых трендов в железе и могли утилизировать несколько ядер. А как дела обстоят с программами? Если программа была написана в строго последовательном стиле то она не сможет утилизировать появившиеся мощности и скорость работы не увеличится.
Поэтому чтобы делать свои программы быстрыми и производительными нужно учиться писать код по другому. Как? Создавать дополнительные дочерние задачи в рамках основной.
Для этого о мультизадачных ОС появились системные вызовы, например:
- Windows: CreateProcess и CreateThread.
- Linux / Unix: clone(2) как основной системный вызов на основе которого реализована функция fork(2) для создания дочернего процесса.
В отличии от Windows в Linux из коробки не было явного API для создания легковесных потоков (для масштабирования использовались процессы с некоторыми оптимизациями) поэтому в начале 2000х была предпринята попытка сделать "свои потоки" (LinuxThreads) но спустя короткое время она была полностью заменена POSIX Threads. POSIX Threads со временем стал дефакто стандартом для работы с потоками и реализации данного API есть для большинства систем.
На этом всё, в данной заметке мы погрузились в проблематику масштабирования CPU и разобрались какие инструменты для разработчиков предоставляет ОС чтобы писать конкурентный код. В следующем посте погрузимся глубже в то как устроены процессы и потоки, какие у них особенности и отличия между собой.
Спасибо что читали, увидимся завтра😊
Доп ссылки:
- Why haven't CPU clock speeds increased in the last 6 years?
- Why multi core processors?
- Advantages and Disadvantages of Multicore Processors
-----
Напоминаю, что моя личка открыта для всех, а если в личку неудобно то можно написать через Google Forms.
Предлагайте темы для будущих постов, задавайте вопросы или оставляйте отзывы/пожелания.😊
Post #306
5.94K
- 👍 34
- 🔥 7
- ❤ 3