Funnelsort - Funnelsort

Funnelsort это на основе сравнения алгоритм сортировки. Это похоже на Сортировка слиянием, но это алгоритм, не обращающий внимания на кеш, разработанный для настройки, в которой количество элементов для сортировки слишком велико, чтобы поместиться в тайник где производятся операции. Его представил Маттео Фриго, Чарльз Лейзерсон, Харальд Прокоп, и Шридхар Рамачандран в 1999 году в контексте кэш забывающая модель.[1][2]

Математические свойства

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

Алгоритм

Базовый обзор

Funnelsort работает с непрерывным массивом элементы. Для сортировки элементов он выполняет следующие действия:

  1. Разделите ввод на массивы размера и рекурсивно отсортируйте массивы.
  2. Слить отсортированные последовательности с использованием -слияние. (Этот процесс будет описан более подробно.)

Funnelsort похож на Сортировка слиянием в том, что некоторое количество подмассивов рекурсивно сортируется, после чего на этапе слияния подмассивы объединяются в один отсортированный массив. Слияние выполняется с помощью устройства, называемого k-слияние, которое описано в следующем разделе.

k-слияние

А k-слияние берет отсортированные последовательности. После одного вызова k-слияния он выводит первое элементы отсортированной последовательности, полученные объединением k входных последовательностей.

На верхнем уровне воронка сортировки использует -слияние на последовательности длины , и вызывает это слияние один раз.

В k-merger строится рекурсивно из -слияние. Это состоит из Вход -слияние , и один выход -слияние . k входы разделены на наборы входы каждый. Каждый из этих наборов является входом для одного из входных слияний. Выход каждого входного слияния подключается к буферу, ФИФО очередь что может держать элементы. Буферы реализованы как круговые очереди.Выходы буферы подключены к входам выходного слияния . Наконец, вывод результат всего k-слияния.

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

А k-merger работает рекурсивно следующим образом. Для вывода элементы, он рекурсивно вызывает слияние выходных данных раз. Однако, прежде чем он позвонит , он проверяет все свои буферы, заполняя каждый из них менее чем наполовину. Чтобы заполнить i-й буфер, он рекурсивно вызывает соответствующее слияние ввода однажды. Если это невозможно сделать (из-за того, что в процессе слияния закончились исходные данные), этот шаг пропускается. Поскольку этот вызов выводит элементов, буфер содержит не менее элементы. В конце всех этих операций k-merger вывел первый элементов ввода в отсортированном порядке.

Анализ

Большая часть анализа этого алгоритма вращается вокруг анализа сложности k-слияния, связанной с пропуском пространства и кэша.

Первая важная граница состоит в том, что k-слияние можно уместить в Космос. Чтобы убедиться в этом, мы позволим обозначают пространство, необходимое для k-слияния. Чтобы соответствовать буферы размера берет Космос. Чтобы соответствовать меньшие буферы занимает Космос. Таким образом, пространство удовлетворяет рекуррентности . Это повторение имеет решение .

Отсюда следует, что существует положительная постоянная так что проблема размера не более полностью помещается в кеш, а это означает, что он не вызывает дополнительных промахов кеша.

Сдача обозначают количество промахов кеша, вызванных вызовом k-слияния, можно показать, что Это делается с помощью индукционного аргумента. Она имеет в качестве базового случая. Для большего k мы можем ограничить количество раз -слияние называется. Выходное слияние называется точно раз. Общее количество требований о слиянии входов не превышает . Это дает общую оценку рекурсивные вызовы. Кроме того, алгоритм проверяет каждый буфер на предмет необходимости его заполнения. Это сделано на буферизует каждый шаг для шаги, ведущие к максимуму промахи в кэше для всех проверок.

Это приводит к повторению , которое, как можно показать, имеет решение, данное выше.

Наконец, отсутствует общий кеш для всего вида можно проанализировать. Удовлетворяет повторению Можно показать, что есть решение

Ленивая воронка

Ленивая воронка является модификацией воронки сортировки, введенной Герт Стёльтинг Бродал и Рольф Фагерберг в 2002 году.[3]Модификация заключается в том, что когда слияние запускается, ему не нужно заполнять каждый из своих буферов. Вместо этого он лениво заполняет буфер только тогда, когда он пуст. Эта модификация имеет ту же асимптотику времени выполнения и передачи памяти, что и исходная сортировка воронок, но имеет приложения в алгоритмах без учета кеширования для задач вычислительной геометрии в методе, известном как поиск распределения.

Смотрите также

Рекомендации

  1. ^ М. Фриго, С.Е. Лейзерсон, Х. Прокоп и С. Рамачандран. Алгоритмы без кеширования. В Материалы 40-го симпозиума IEEE по основам компьютерных наук (FOCS 99), стр. 285-297. 1999 г. Расширенная аннотация в IEEE, в Citeseer.
  2. ^ Харальд Прокоп. Алгоритмы, не обращающие внимания на кеш. Магистерская диссертация, Массачусетский технологический институт. 1999 г.
  3. ^ Бродал, Герт Стёльтинг; Фагерберг, Рольф (25 июня 2002 г.). «Незаметная очистка кеша». Автоматы, языки и программирование. Конспект лекций по информатике. 2380. Springer. С. 426–438. CiteSeerX  10.1.1.117.6837. Дои:10.1007/3-540-45465-9_37. ISBN  978-3-540-43864-9. Cite имеет пустой неизвестный параметр: |1= (помощь). См. Также более длинный технический отчет.