Лифтовой алгоритм Линуса

Лифтовой алгоритм Линуса

Рассмотрим некоторые планировщики ввода-вывода, применяемые в реальной жизни. Первый планировщик ввода-вывода, который мы рассмотрим, называется Linus Elevator (лифтовой алгоритм Линуса). Это не опечатка, действительно существует лифтовой планировщик, разработанный Линусом Торвальдсом и названный в его честь! Это основной планировщик ввода-вывода в ядре 2.4. В ядре 2.6 его заменили другими планировщиками, которые мы ниже рассмотрим. Однако поскольку этот алгоритм значительно проще новых и в то же время позволяет выполнять почти те же функции, то он заслуживает внимания.

Лифтовой алгоритм Линуса позволяет выполнять как объединение, так и сортировку запросов. Когда запрос добавляется в очередь, вначале он сравнивается со всеми ожидающими запросами, чтобы обнаружить все возможные кандидаты на объединение. Алгоритм Линуса выполняет два типа объединения: добавление в начало запроса (front merging) и добавление в конец запроса (back merging). Тип объединения соответствует тому, с какой стороны найдено соседство. Если новый запрос следует перед существующим, то выполняется вставка в начало запроса. Если новый запрос следует сразу за существующим — добавление выполняется в конец очереди. В связи с тем, что секторы, в которых хранится файл, расположены по мере увеличения номера сектора и операции ввода-вывода чаще всего выполняются от начала файла до конца, а не наоборот, то при обычной работе вставка в начало запроса встречается значительно реже, чем вставка в конец. Тем не менее алгоритм Линуса проверяет и выполняет оба типа объединения.

Если попытка объединения была неудачной, то определяется возможное место вставки запроса в очередь (положение в очереди, в котором новый запрос наилучшим образом вписывается по номеру сектора между окружающими запросами). Если такое положение находится, то новый запрос помещается туда. Если подходящего места не найдено, то запрос помещается в конец очереди. В дополнение к этому, если в очереди найден запрос, который является достаточно старым, то новый запрос также добавляется в конец очереди. Это предотвращает ситуацию, в которой наличие большого количества запросов к близко расположенным секторам приводит к недостатку обслуживания других запросов. К сожалению, такая проверка "на старость" не очень эффективна. В рассмотренном алгоритме не предпринимается никаких попыток обслуживания запросов в заданных временных рамках, а просто прекращается процесс сортировки-вставки при наличии определенной задержки. Это в свою очередь приводит к задержке в обслуживании, что было веской причиной для доработки планировщика ввода-вывода ядра 2.4.

Итак, когда запрос добавляется в очередь возможны четыре типа действий. Вот эти действия в необходимой последовательности.

• Если запрос к соседнему сектору находится в очереди, то существующий запрос и новый объединяются в один.

• Если в очереди существует достаточно старый запрос, то новый запрос помещается в конец очереди, чтобы предотвратить отказ обслуживания для других запросов, которые долгое время находятся в очереди.

• Если для секторов данного запроса в очереди существует позиция, которая соответствует рациональному перемещению между секторами, то данный запрос помещается в эту позицию, что позволяет поддерживать очередь в отсортированном состоянии.

• И наконец, если такая позиция не найдена, то запрос помещается в конец очереди.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

8.1.1 Алгоритм

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

8.1.1 Алгоритм Сразу после переключения контекста ядро запускает алгоритм планирования выполнения процессов (Рисунок 8.1), выбирая на выполнение процесс с наивысшим приоритетом среди процессов, находящихся в состояниях "резервирования" и "готовности к выполнению, будучи


Алгоритм iter_swap()

Из книги C++ для начинающих автора Липпман Стенли

Алгоритм iter_swap() template class ForwardIterator1, class ForwardIterator2 voiditer_swap( ForwardIterator1 a, ForwardIterator2 b );iter_swap() обменивает значения элементов, на которые указывают итераторы a и b.#include algorithm#include list#include iostream.hint main(){int ia[] = { 5, 4, 3, 2, 1, 0 };list int,allocator ilist( ia, ia+6 );typedef list int, allocator ::iterator iterator;iterator iter1 =


Алгоритм lexicographical_compare()

Из книги Новый ум короля [О компьютерах, мышлении и законах физики] автора Пенроуз Роджер

Алгоритм lexicographical_compare() template class InputIterator1, class InputIterator2 boollexicographical_compare(InputIterator1 first1, InputIterator1 last1,InputIterator1 first2, InputIterator2 last2 );template class InputIterator1, class InputIterator2,class Compare boollexicographical_compare(InputIterator1 first1, InputIterator1 last1,InputIterator1 first2, InputIterator2 last2,Compare comp );lexicographical_compare() сравнивает соответственные пары


Алгоритм lower_bound()

Из книги автора

Алгоритм lower_bound() template class ForwardIterator, class Type ForwardIteratorlower_bound( ForwardIterator first,ForwardIterator last, const Type &value );template class ForwardIterator, class Type, class Compare ForwardIteratorlower_bound( ForwardIterator first,ForwardIterator last, const Type &value,class Compare );lower_bound() возвращает итератор, указывающий на первую позицию в отсортированной


Алгоритм max()

Из книги автора

Алгоритм max() template class Type const Type&max( const Type &aval, const Type &bval );template class Type, class Compare const Type&max( const Type &aval, const Type &bval, Compare comp );max() возвращает наибольшее из двух значений aval и bval. В первом варианте используется оператор "больше", определенный в классе Type; во втором - операция


Алгоритм min()

Из книги автора

Алгоритм min() template class Type const Type&min( const Type &aval, const Type &bval );template class Type, class Compare const Type&min( const Type &aval, const Type &bval, Compare comp );min() возвращает меньшее из двух значений aval и bval. В первом варианте используется оператор “меньше”, определенный для типа Type; во втором - операция


Алгоритм merge()

Из книги автора

Алгоритм merge() template class InputIterator1, class InputIterator2,class OutputIterator OutputIteratormerge( InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, InputIterator2 last2,OutputIterator result );template class InputIterator1, class InputIterator2,class OutputIterator, class Compare OutputIteratormerge( InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp );merge() объединяет


Алгоритм mismatch()

Из книги автора

Алгоритм mismatch() template class InputIterator1, class InputIterator2 pairInputIterator1, InputIterator2mismatch( InputIterator1 first,InputIterator1 last, InputIterator2 first2 );template class InputIterator1, class InputIterator2,class BinaryPredicate pairInputIterator1, InputIterator2mismatch( InputIterator1 first, InputIterator1 last,InputIterator2 first2, BinaryPredicate pred );mismatch() сравнивает две последовательности и находит


Алгоритм nth_element()

Из книги автора

Алгоритм nth_element() template class RandomAccessIterator voidnth_element( RandomAccessIterator first,RandomAccessIterator nth,RandomAccessIterator last );template class RandomAccessIterator, class Compare voidnth_element( RandomAccessIterator first,RandomAccessIterator nth,RandomAccessIterator last, Compare comp );nth_element() переупорядочивает последовательность, ограниченную диапазоном [first,last), так что все


Алгоритм partial_sort()

Из книги автора

Алгоритм partial_sort() template class RandomAccessIterator voidpartial_sort( RandomAccessIterator first,RandomAccessIterator middle,RandomAccessIterator last );templatepartial_sort() сортирует часть последовательности, укладывающуюся в диапазон [first,middle). Элементы в диапазоне [middle,last) остаются неотсортированными. Например, если дан массивint ia[] =


Алгоритм partial_sum()

Из книги автора

Алгоритм partial_sum() template class InputIterator, class OutputIterator OutputIteratorpartial_sum(InputIterator first, InputIterator last,OutputIterator result );template class InputIterator, class OutputIterator,class BinaryOperation OutputIteratorpartial_sum(InputIterator first, InputIterator last,OutputIterator result, BinaryOperation op );Первый вариант partial_sum() создает из последовательности, ограниченной


Алгоритм partition()

Из книги автора

Алгоритм partition() template class BidirectionalIterator, class UnaryPredicate BidirectionalIteratorpartition(BidirectionalIterator first,BidirectionalIterator last, UnaryPredicate pred );partition() переупорядочивает элементы в диапазоне [first,last). Все элементы, для которых предикат pred равен true, помещаются перед элементами, для которых он равен false.


Алгоритм random_shuffle()

Из книги автора

Алгоритм random_shuffle() template class RandomAccessIterator voidrandom_shuffle( RandomAccessIterator first,RandomAccessIterator last );template class RandomAccessIterator,class RandomNumberGenerator voidrandom_shuffle( RandomAccessIterator first,RandomAccessIterator last,RandomNumberGenerator rand);random_shuffle() переставляет элементы из диапазона [first,last) в случайном порядке. Во втором варианте можно