Как эффективно отсортировать список элементов переменного размера? - PullRequest
0 голосов
/ 17 сентября 2018

Моя мотивация для этого состоит в том, чтобы написать код сборки Z80 для сортировки таблицы распределения переменных (НДС) серии TI-83 +, но я также заинтересован в этом как в общей проблеме.

Часть НДС, которую я хочу отсортировать, упорядочена в непрерывной памяти, где каждый элемент состоит из данных фиксированного размера, за которыми следует байт размера для имени, а затем имя. Чтобы усложнить ситуацию, по обе стороны от НДС расположены два стека, которые не дают места для маневра для безопасного заполнения выделенной оперативной памятью.

В идеале, я хотел бы использовать O (1) пробел, поскольку у меня есть готовый доступ к 2 768-байтовым буферам непользовательской оперативной памяти. Я также хочу сделать это быстро, так как он может содержать много записей, и это процессор с тактовой частотой 6 МГц (хотя, по сути, 1MIPS - без конвейера команд). Также важно отметить, что каждая запись имеет не менее 8 байтов и не более 15 байтов.

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

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

1 Ответ

0 голосов
/ 17 сентября 2018

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

Вместо N-способного слияния может быть проще всего отсортировать N попарно с помощью 2-стороннего слияния.

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

Для копирования данных инструкции по перемещению блока Z-80 LDIR и LDDR довольно дороги, но их трудно превзойти. Развертывание LDIR в серию LDI может быть быстрее. Указание указателя стека на источник и назначение и использование нескольких POP, а затем PUSH может быть быстрее, но требует, чтобы прерывания были отключены и гарантировалось отсутствие немаскируемых прерываний.

...