Простейшим типом поддержки со стороны операционной системы является одинарный буфер (рис. 11.6,6). В тот момент, когда пользовательский процесс выполняет запрос ввода-вывода, операционная система назначает ему буфер в системной части основной памяти.
Схема одинарного буфера для блочно-ориентированных устройств может быть описана следующим образом. Сначала осуществляется передача входных данных в системный буфер. Когда она завершается, процесс перемещает блок в пользовательское пространство и немедленно производит запрос следующего блока. Такая процедура называется опережающим считыванием, или упреждающим вводом; она выполняется в предположении, что этот блок со временем будет затребован. Для многих типов задач этот метод в большинстве случаев неплохо работает, поскольку доступ к данным обычно осуществляется последовательно (только при окончании последовательности обработки считывание блока будет излишним).
Такой подход, по сравнению с отсутствием буферизации, обеспечивает повышение быстродействия. Пользовательский процесс может обрабатывать один блок данных в то время, когда происходит считывание следующего блока. Операционная система при этом может осуществить выгрузку процесса, поскольку выполняется операция считывания данных в системную память, а не в память пользовательского процесса. Однако такая технология усложняет функционирование операционной системы, которая должна следить за назначением системных буферов пользовательским процессам. Влияет буферизация и на схему подкачки: когда операция ввода-вывода работает с тем же диском, который используется и для свопинга, теряется смысл в организации очереди операций записи. Выгрузка процесса и освобождение основной памяти не начнется до тех пор, пока не завершится запрошенная операция ввода-вывода — а тогда выгрузка процесса больше не будет иметь смысла.
Рис. 11.6, Схемы буферизации ввода-вывода (ввод)
Похожие рассуждения применимы и к блочно-ориентированному выводу. Если данные передаются на устройство, то сначала они копируются из пользовательского пространства в системный буфер, из которого они в конечном счете будут записаны на устройство. В этой ситуации выводящий данные процесс может продолжать работу сразу же после передачи данных в системный буфер.
В книге [KNUT97] приводится грубое, но очень показательное сравнение процессов при использовании одинарной буферизации и при ее отсутствии. Предположим, что Т — это время, необходимое для ввода одного блока, а С — для вычислений, выполняющихся между запросами на ввод данных. Без буферизации общее время выполнения, приходящееся на один блок, будет равно Т + С. При использовании одинарной буферизации время выполнения равно mах[С, Т] + М, где М — время, необходимое для перемещения данных из системного буфера в пользовательскую память. В большинстве случаев это время значительно меньше времени работы без буферизации.
Схема одинарного буфера может быть применена и при поточно-ориентированном вводе-выводе — построчно или побайтово. Построчная буферизация применима, например, в неинтеллектуальных терминалах, где пользователь вводит данные построчно, завершая строки символом возврата каретки, сигнализируя об окончании строки; вывод на терминал происходит таким же образом — построчно. Другим примером может служить строчный принтер. Побайтовые операции применяются при использовании терминалов с формами, а также многих других периферийных устройств, когда каждое нажатие клавиши является значимым.
В случае построчного ввода-вывода буфер может быть использован для хранения одной строки. Пользовательский процесс приостанавливается на время ввода, ожидая поступления целой строки. При операции вывода пользовательский процесс может разместить строку в буфере и продолжить работу. Необходимость приостановления этого процесса возникает только в том случае, если требуется вывод второй строки, в то время как первая еще не покинула буфер. При побайтовом вводе-выводе, взаимодействие операционной системы и пользовательского процесса следует модели производителя/потребителя, рассмотренной в главе 5, "Параллельные вычисления: взаимоисключения и многозадачность".