[МУЗЫКА] [МУЗЫКА] Рассмотрим теперь организацию ввода-вывода к компьютерах. Представить себе электронно-вычислительную машину, которая не умеет ни читать, ни писать, и вообще не видит внешний мир, невозможно. Имеено для этого они были придуманы — чтобы регаировать на какие-то сигналы из внешнего мира, проводить какие-то расчеты и выдавать их человеку как результат. Исторически первыми внешними устройствами были, как ни странно, перфокарты. Они были изобретены совершенно для других целей французом Жаккардом в 1801 году. Жаккард изобрел станки для плетения тканей с узорами. Знаете, бывают ткани, там, свитер, на котором нарисованы олени или еще что-нибудь такое. Так вот, это было изобретено уже больше 200 лет назад и тогда перфокарта представляла собой такой довольно большой квадрат, на который были нанесены дырочки. Такая перфокарта вставлялась в ткацкий станок, там какие-то контакты, и наличие дырки в определенном месте заставляло станок как-то менять направление движения нити. Потом, в конце 19-го века, Герман Холлерит эти перфокарты как-то преобразовал. Такие были узкие полоски, я их хорошо помню, на них долго работал. На этих перфокартах, с помощью специальных устройств, табуляторов (это еще далеко не ЭВМ, это такие механические, совершенно механические устройства) была произведена перепись населения США в конце 19 века. И причем это произошло как-то быстро, аккуратно, с меньшим количеством ошибок и потерь. Всем страшно понравилось. Благодаря этому успеху в переписи населения США Герман Холлерит в 1896 году создал компанию, Tabulating Machine Company, эта компания бурно развивалась. К 1911 году она была объединена с какой-то другой компанией, а в 1924 году эту компанию без всякого iii, просто была переименова в компанию IBM. Таким образом IBM праздновала 100-летие два раза — в 1996 году и в 2011 году. Это было бурное празднование — все-таки старейшая компьютерная компания мира. И в общем, надо признать, довольно уважаемая компания. Так вот, вернемся к операциям ввода-вывода. Ведь глупо, если центральный процессор попросите прочитать одну перфокарту, и в это время будете спокойно сидеть и ждать, и ничего не делать. Огромные потери. Поэтмоу в той же компании IBM в середине 50-х годов уже 20 века, естественно, были изобретены специальные устройства, которые называются каналы. Канал — это маленькая ЭВМ, со своей памятью, своим устройством управления, но эта ЭВМ умеет делать только одну операцию: читать или писать перфокарту. Другая ЭВМ, другой канал, может читать или писать перфоленту, третий — читать или писать на диск, и так далее. То есть для каждого устройства образуется свой канал. В центральном процессоре есть всего одна команда. SIO — Start Input/Output. Так вот, центральный процессор запускает команду SIO, параметром является номер канала, и просто продолжает свою работу. В это время канал, это же настоящая независимая ЭВМ, работает. iii разбирать на примере диска. Находит нужный цилиндр, то есть вот там лапа такая двигается в диске, находит нужное место, ждет появления определенного маркера начала трека, читает или пишет. Все это занимает довольно большое время, поскольку вовлечены механические устройства, а механические устройства не могут очень быстро работать поскольку там есть масса, мера инерции как вы знаете. Так вот, когда операция закончена, которая может занять довольно большое время, канал вызывает прерывание в центральной машине и в центральном процессоре, и тогда процессор понимает, что заказанная ему операция ввода-вывода закончена, и продолжает работу. На самом деле, конечно, никто не обращается за одним байтом или за пятью байтами. Все-таки это довольно большая операция, поэтому стараются обращаться к каналам за какими-то более-менее большими порциями данных. Такая порция данных фиксированного размера называется блоком. Блок это просто размер, то есть какая-то определенная порция данных. Чаще всего эти 3-4 килобайта. Центральный процессор обращается за операцией чтения-вывода к каналу за блоком, и канад отрабатывает этот блок. Но это не всегда удобно. Может быть вам нужно иметь какую-то логическую единицу данных. Скажем, 10-15 байтов, а не 4000 байтов. Тогда принято говорить, что блок делится на записи фиксированного размера, и блок состоит их многих записей. Канал читает блог, а уже потом операционная система этот блок разбивает на записи. Мне важно подчеркнуть здесь только одно, что и канал, и процессор всегда работают параллельно, независимо друг от друга, и поэтому iii можно быстро ускорять. Процессор не теряет ни одного такта. Посмотрим такую задачу: пусть вам надо прочитать (ну, все равно — прочитать, записать, рассмотрим на примере прочитать) большой-большой файл, в котором много тысяч блоков. Представляете, вы прочитали блок, процессор начал его обрабатывать, тоже какое-то время занимает. Канал простаивает. Потом вам надо прочитать следующий блок, тогда процесс работы простаивает. В таком случае применяется специальный механизм, который называется буферизация. Давайте разберем его на простом примере: пусть у вас есть два буфера, каждый размером с блок. Первый раз вы теряете время, читаете первый блок. Но потом вы каким-то регистром быстрым переключаете адрес на второй блок, и в это время процессор может обрабатывать первый уже прочитанный блок пока читается второй. К тому моменту когда процессор кончит обработку первого блока, у вас уже прочитан второй блок и так далее. Если вам мало, то есть как-то в отношении скоростей обработки, можно увеличить количество блоков, можно менять их размеры, но важно, что всегда процессор какой-то блок обрабатывает, а другие блоки в это время читаются. Поэтому процессор будет постоянно загружен. На самом деле размер блока, количество буферов, это довольно тонкая наука, которая может очень существенно повлиять на скорость обработки. Например, когда я был молодой, мы работали с дисками IBM-овскими и длина трека была 7600 байтов. Естественно, мы по молодости и блоки делали 7600 байтов. Но заметили, что машина начинает работать как утюг, медленно. И вот мы пытались разобраться, в чем дело. Оказалось, что в каждом треке, который имеет размер 7600 байтов, есть специальный маркер, который указывате на начало трека, на нулевой адрес трека. Если вы заказали размер блока 7600 байтов, вы прочитали 7600 байтов, тем самым вы прочитали полный трек. Вам надо читать следующий блок, скажем, на том же цилиндре, но другой трек, а диск-то крутится постоянно, и он уже маркерт проскочил. Получается, что надо делать лишний оборот. И мы экспериментально подобрали, я на всю жизнь буду помнить — 7340, такая мировая константа. Надо же сделать максимально возможно большой блок, чтобы ничего не терялось. Так вот, если сделать 7340 байтов размер блока, то диск успевал схватить следующий трек без лишнего оборота. Просто в два раза ускорилась работа программы, в два раза. Просто изменяя размер блока. Вы знаете, мне это интересно и сейчас, что изменилось в сегодняшний день. Поэтому я время от времени поручаю своим студентам проводить аналогичные эксперименты. Вот буквально в этом учебном году мой студент Денис Смирнов провел похожий эксперимент. Просто на сегодняшних устройствах ввода-вывода, но ровно те же самые эксперименты как мы делали 30-40 лет назад. Оказалось, что если сделать размер блока при работает с диском 4095 байтов, то работает быстро, а если сделать размер 4096, на 1 байт больше, работает в два раза медленнее. Каждый может повторить этот эксперимент, если не верит. Я-то, в общем, нисколько не удивился — ничто не ново под луной. Все то, что мы открывали 30-40 лет назад работает и сегодня, просто в других масштабах, в других цифрах. Заметьте, уважаемые слушатели, зная вот эту фразу, вы тоже можете оптимизировать свои программы, причем не на проценты, а в разы. То есть зная размер трека, зная размер блока, управляя размером блока, размером записи, количеством буферов, вы можете ускорить свою программу в разы, и это не шутка. Теперь, как завершать операции ввода-вывода? Есть два способа завершения операции ввода-вывода. Один способ — ввод по прерыванию. То есть канал выдает прерывание, как я уже сказал. Это основной способ работы. Другой способ — программируемый ввод-вывод, когда центральный процессор просто время от времени сам опрашивает каналы, чтобы узнать, закончилась работа или нет. И вы знаете, этот способ тоже очень активно применяется. И мы его используем. Например, вы программируете цифровую телефонную станцию. Там этих регистров столько же, сколько абонентов, сколько iii к другим станциям — тысячи, десятки тысяч. Так вот, если вы думаете на каждый из них делать прерывание, вам никаких ресурсов машины не хватит. Вместо этого делается следующее: каждое устройство ввода-вывода снабжается примерным триггером, в котором 0 если операция если еще не закончилась, 1 если уже закончилась. Центральный процессор циклично, скажем, каждые 10 или 100 миллисекунд опрашивает все эти тысячи триггеров, и если встречает 1, тогда понимает, что канал закончил свою работу, и завершает операцию ввода-вывода. Такой процесс часто называют сканированием. Еще раз повторяю, что сканирование применяется в основном во встроенных устройствах реального времени, таких как телефонные станции, ракеты, медицинские устройства. Обработка окончания ввода-вывода по прерыванию в нормальных условиях, диски, ленты и так далее. Таким образом мы рассмотрели основы организации ввода-вывода, как операция начинается, как операция заканчивается. Детальное описание устройств мы рассмотрим в следующих разделах. [БЕЗ_ЗВУКА]