Ответ
В ранних компьютерных архитектурах параллелизм достигался преимущественно на аппаратном уровне за счет следующих механизмов:
-
Конвейерная обработка инструкций (Pipelining) Процесс выполнения инструкции разбивался на независимые этапы (выборка, декодирование, исполнение, запись результата). Это позволяло процессору одновременно обрабатывать несколько инструкций, находящихся на разных этапах конвейера.
-
Использование сопроцессоров Специализированные процессоры (например, FPU для операций с плавающей запятой или GPU для графики) работали параллельно с центральным процессором (CPU), разгружая его от специфических вычислений.
-
Прямой доступ к памяти (DMA - Direct Memory Access) Контроллер DMA позволял периферийным устройствам (например, жесткому диску) обмениваться данными с оперативной памятью напрямую, без участия и контроля со стороны CPU, освобождая его для других задач.
-
Аппаратные прерывания (Interrupts) Позволяли процессору асинхронно реагировать на внешние события (например, ввод с клавиатуры или завершение операции ввода-вывода), приостанавливая текущую задачу, обрабатывая событие и затем возобновляя работу. Это создавало эффект многозадачности.
Эти методы позволяли эффективно утилизировать ресурсы и повышать производительность еще до появления многоядерных процессоров.
Ответ 18+ 🔞
Да ты послушай, как раньше-то компьютеры выкручивались, чтобы хоть как-то параллельно работать! Никаких там восьми ядер, один кристалл, и тот еле шевелится. Но инженеры-то не лыком шиты, придумали такие фокусы, что диву даёшь.
Вот, например, конвейер инструкций (Pipelining). Представь себе заводскую линию. Одна работяга только деталь берёт, второй её крутит, третий закручивает, четвёртый в коробку кладёт. Так и тут: одну команду разбили на этапы — достали, расшифровали, выполнили, записали. И пока первая команда результат пишет, вторая уже выполняется, третья расшифровывается, а четвёртая только-только из памяти вылезает. Гениально же! Не ждать же, пока одна операция полностью упырится, можно по чуть-чуть, но несколько сразу гонять. Производительность подскакивала, как ужаленная.
А ещё любили сопроцессоры прикручивать. Ну, главный мозг (CPU) он, конечно, универсальный солдат, но, блядь, считать дроби или картинки рисовать — это для него как мартышке ананас чистить: долго и муторно. Так вот, брали и ставили рядом спеца — математический сопроцессор (FPU) или графический (GPU). Сказал ему: «На, ебёшь эти числа!», а сам в это время другие дела делаешь. Параллелизм в чистом виде, ёпта! Каждый занимается своим делом, не мешая друг другу.
Но самый цимес был, конечно, прямой доступ к памяти (DMA). Вообрази: процессор сидит, важные вычисления ведёт, а тут ему надо гигабайты с диска в память перекинуть. Если бы он сам этим занимался, то до утра бы ковырялся. А тут приходит такой крутой чувак — контроллер DMA — и говорит: «Расслабься, братан, я сам всё улажу. Ты дай только команду «начать», а дальше я напрямую с памятью договорюсь, тебя даже беспокоить не буду». И процессор, довольный, продолжает свои алгоритмы гонять, пока на заднем плане идёт тихая, ебаная перекачка данных. Красота!
Ну и куда же без аппаратных прерываний (Interrupts). Это ж вообще основа всей многозадачности! Сидит программа, упорото в цикле крутится, и тут — раз! — пользователь клавишу нажал. Что делать? Ждать, пока цикл кончится? Так пользователь сдохнет от нетерпения. Вот и придумали систему прерываний: железо дёргает процессор за рукав, кричит: «Эй, мудак, срочное дело!». Процессор быстренько сохраняет, где он остановился, переключается на обработчик прерывания (маленькую программу-служанку), та клавишу обрабатывает, а потом он возвращается к своей программе, как ни в чём не бывало. И так десятки раз в секунду! Со стороны кажется, что всё работает одновременно, а на самом деле это один чувак мечется между задачами, как угорелый. Волшебство, блядь, да и только.
Вот так и выкручивались, без всяких многоядерностей. Всё на смекалке, проводах и святом духе. Ёперный театр, сейчас-то проще, а тогда каждый процент производительности выжимали, как последний сок.