AOP_Tom1 (1021736), страница 60
Текст из файла (страница 60)
Поэтому средства ввода-вывода компьютера обычно начинают изучать только после знакомства с остальными его возможностями. И часто случается так, что лишь небольшая группа программистов некоторого компьютера вообще что-либо знает о деталях операций ввода-вывода. Такое положение вещей в чем-то даже естественно, поскольку программирование ввода-вывода никогда не было особенно привлекательным. Но до тех пор, пока многие не начнут серьезно относиться к данному предмету, нельзя ожидать, что ситуация изменится. В этом и других разделах (налример, в разделе 5.4.б) вы увидите, что в связи с вводом-выводом возникает множество интересных вопросов, а также узнаете о существовании некоторых изящных алгоритмов. Теперь, пожалуй, нужно сделать небольшое отступление по поводу терминологии.
В словарях английского языка слова ")прп!" ("ввод") и "опгрп!" ("вывод") раньше приводились только как существительные ("ЪЧЬа! Ыпб ог )прп! аге че Беы г)пБ?" — "Какого вида данные мы вводим?" ). Но теперь уже вошло в привычку использовать их как прилагательные ("Роп'с огор гЬе )прпт саре" — "Не сотрите эту ленту с входными данными") и переходные глаголы ("71Ъу ЙЙ $Ье ргояташ оп!рп! СЬ)в яагЬайе?» — "Почему программа выводит эту чепуху?"). Вместо комбинированного термина "ввод-вывод" чаще всего используют аббревиатуру "В/В" (на английском — "1/О"). Операцию ввода часто называют чшением, а вывода соответственно записью. Элементы, составляющие ввод или вывод, обычно называют "данными" (на английском — "паса").
В английском языке это слово, строго говоря, является формой множественного числа (как и в русском языке. — Прим. перев.), но используется в собирательном смысле, как будто это единственное число ("ТЬе г!ага Ьав гю! Ьееп геаг!."). Точно так и слово "!п(отша!!оп" ("информация") является формой как единственного, так и множественного числа. На этом урок английского закончен. Предположим, необходимо прочитать данные с магнитной ленты.
Оператор 1М машины М11, как описано в разделе 1.3,1, просто иницннруеш процесс ввода, и в то время, пока данные вводятся, компьютер продолжает выполнять следующие команды. Поэтому по команде "1М 1000(5)" начинается считывание 100 слов с накопителя на магнитных лентах под номером 5 в ячейки памяти 1000 — 1099, но последующие команды программы пока не должны обращаться к этим ячейкам. Программа может считать, что ввод завершен только после тога, как (а) инициируется другая операция В/В (1М, 007 или 100), обращающаяся к устройству 5, или (Ь) команда условного перехода ЛВВБ(5) или ЗВЕВ(5) показывает, что устройство 5 больше не "занято".
Поэтому самый простой способ считать блок данных с ленты в ячейки 1000-1099 так, чтобы информация была на месте, — воспользоваться двумя командами: 1М 1000(5); ЯВИ я(5). (1) Этот элементарный метод применялся в программе из раздела 1.4.2 (см. строки 07- ОВ и 52 — 53). Но он слишком неэкономно расходует время работы компьютера, так как большая часть времени, которую можно было бы использовать для вычислений, скажем 1000и или даже 10000и, тратится на многократное повторение команды "ЗВОБ". Если это время использовать для вычислений, то скорость выполнения программы можно удвоить. (См.
упр. 4 и 5.) Один из способов избежать такою "цикла ожидания" — использовать две области памяти для ввода. Можно считывать данные в одну область, в то же время выполняя вычисления над данными в другой. Например, программу можно начать командой 1М 2000(5) Начать чтение первого блока.
(2) И теперь каждый раз, когда понадобится прочитать блок с ленты, можно дать пять следующих команд. ЕМТ1 1000 Подготовиться к выполнению оператора МОЧЕ. ЗВОЯ ь (5) Ожидать готовности устройства 5. МОЧЕ 2000(50) (2000-2049) -+ (1000-1049). (3) МОЧЕ 2050(50) (2050-2099) -+ (1050-1099).
1М 2000(5) Начать чтение следующего блока. В целом., это дает такой же эффект, как и применение команды (1), но лента с входными данными остается занятой, пока программа работает над данными, находящимися в ячейках 1000 — 1099. Последняя команда (3) начинает считывание блока данных с ленты в ячейки 2000 — 2099 до того, как был обработан предыдущий блок. Это называется досрочным чтением или опережаюи1им вводом и делается в расчете на то, что данный блок в конце концов понадобится.
Но на самом деле, начав обработку блока в ячейках 1000 — 1099, можно обнаружить, что никаких данных больше не нужно. Мы уже встречались с аналогичной ситуацией, например, в сопрограмме из раздела 1.4.2, где входные данные поступали с перфокарт, а не с ленты. Появление "." в любом месте перфокарты означало, что это последняя карта колоды. Подобная ситуация делает опережающий ввод невозможным. Исключение составляют случаи, когда можно предположить, что (а) за колодой перфокарт с входными данными следует пустая перфокарта или специальная дополнительная карта некоторого другого вида, либо (Ь), скажем, в колонке ВО последней карты колоды появляется опознавательная метка (например, "."). При использовании опережающего ввода для правильного завершения ввода в конце программы всегда должны быть предусмотрены специальные средства. Метод параллельного выполнения вычислений и операций В/В называется буферизацией, в то время как элементарный метод (1) называется небуферизироеанимм вводом.
Область ячеек памяти 2000 — 2099, которая используется для сохранения опережающею ввода в (3), а также область ячеек 1000-1099, в которые перемещаются входные данные, называется буфером. В словаре Вебстера (ЖЧеЬвсег) №в Иог!д Р)сбопагу слово "буфер" определяется как "Любой человек или предмет, который служит для смягчения удара'". Этот термин нам подходит, так как для буферизации характерна более ровная работа устройств В/В.
(Инженеры-электронщики часто используют слово "буфер" в другом смысле, обозначая им часть устройства В/В, в которой сохраняется информация во время ее передачи. Но в этой книге 01 ЫОНО1И ОБ ОЮ 2Н 04 00 1Н 00 07 08 00 1МВОР1 10 10 1НВОР2 !Я Ц БТЛ 1Р 1НСБ 1 ЕОА 0,6 СМРА =БЕНТ1МЕ1. ЛМЕ 1М -100,6(О) ЕОБ 1,Б ЗМР 2В ОН16 э+100 СОН БЕМТ1НЕЕ СОН ээ1 ОК16 в+100 СОН БЕНТ1НЕЕ СОН 1НВОР1 Сохранить адрес выхода. Перейти к следующему слову. Это конец буфера? Если нет, выйти. Пополнить этот буфер. Переключиться на другой буфер и вернуться. Первый буфер.
Маркер конца буфера. Адрес другого буфера. Второй буфер. Маркер конца буфера. Адрес другого буфера. 1 (4) В этой программе для адресации последнего слова ввода используется регистр 6. Предполагается, что вызывающая программа не изменяет его значение. Символ О термин "буфер" будет означать область помяши, используемую программистом для хранения данных В/В.) ' Последовательность (3) не всегда лучше, чем (1), хотя исключения из этого правила достаточно редки.
Давайте сравним их время выполнения. Пусть Т— время, необходимое для ввода 100 слов, и пусть С вЂ” время выполнения, которое проходит между запросами на ввод данных. Для метода (1) требуется, в основном, Т + С времеви на блок ленты, а для метода (3) — в основном, шах(С,Т) + 202и. (Величина 202и — это время, необходимое для выполнения двух команд МОЧЕ.) Один из способов оценки времени выполнения состоит в том, чтобы рассмотреть время прохождения критического пути; в данном случае — промежуток времени между моментами использования устройства В/В, в течение которого оно не занято.
В методе (1) устройство остается незанятым в течение С единиц времени, а в методе (3) — 202 единиц времени (в предположении, что С ( Т). Относительно медленно работающие команды МОЧЕ из (3) использовать нежелательно, особенно потому, что они отнимают время прохождения критического пути, когда накопитель на магнитной ленте должен быть неактивным. Но существует почти очевидный способ улучшения этого метода, который позволит избежать использования команд МОЧЕ. Внешнюю программу можно переделать тэк, чтобы она обращалась поочередно к ячейкам 1000 — 1099 н 2000 — 2099. Во время считывания данных в один буфер можно выполнять вычисления в другом буфере; затем можно начать считывание в другой буфер, в то же время проводя вычисления над данными в первом буфере.
Этот важный метод называется сеопингом. Адрес текущего буфера сохраняется в индексном регистре (или, если нет свободных индексных регистров, в ячейке памяти). Мы уже встречались с методом свопинга, когда он применялся к выходным данным алгоритма 1.3.2Р (см. шаги Р9 — Р11) и к сопутствующей программе, Рассмотрим пример применения метода свопинга ко вводу.
Предположим, каждый блок ленты состоит из 100 отдельных элементов, содержащих по одному слову. Ниже приведена подпрограмма, которая берет следующее слово из входных данных и начинает считывание нового блока, если текущий исчерпан. обозначает накопитель на магнитной ленте, а символ ЯЕМТ1ЕЕŠ— это значение, о котором известно (из характеристик программы), что его нет ни в одном блоке на ленте. По поводу данной подпрограммы необходимо отметить следующее. 1) Константа-маркер (зепи! пе1) появляется в качестве 101-го слова каждого буфера и представляет собой удобное средство для обозначения окончания буфера.
Но во многих задачах этот метод не будет надежным, так как на ленте может появиться любое слово. Если вводить данные с перфокарт, то подобный метод (когда 17-е слово буфера является маркером) всегда можно использовать, не опасаясь сбоя. В этом случае маркером может служить любое отрицательное число, так как при вводе в И1Х с перфокарт всегда получаются неотрицательные слова. 2) В каждом буфере содержится адрес другого буфера (см.