Повлияет ли аппаратное обеспечение / реализация на временную / пространственную сложность алгоритмов?


32

Я даже не студент CS, так что это может быть глупым вопросом, но, пожалуйста, потерпите меня ...

В до-компьютерную эпоху мы можем реализовать структуру данных массива только с чем-то вроде массива ящиков. Так как перед извлечением значения из него нужно найти ящик с соответствующим индексом, временная сложность поиска в массиве составляет , предполагая бинарный поиск.О(Lог(N))

Однако изобретение компьютеров имело большое значение. Современные компьютеры могут читать из своей оперативной памяти так быстро, что теперь мы считаем, что временная сложность поиска в массиве равна (даже технически это не так, поскольку для перемещения регистра на большее расстояние и т. Д. Требуется больше времени)О(1)

Другой пример - словари Python. В то время как можно получить сложность доступа к словарю с плохо написанным перегруженным магическим методом (или смехотворной неудачей, то есть ключами, имеющими много коллизий хешей), обычно предполагается, что . В этом случае сложность времени зависит как от реализации хеш-таблиц словарей Python, так и от реализации ключей хеш-функций.О(N)__hash__О(1)

Означает ли это, что аппаратное обеспечение / реализация может влиять на временную сложность алгоритмов? (Хотя оба примера касаются структур данных, а не алгоритмов, последние основаны на первом, и я никогда не слышал о временной сложности структур данных, поэтому здесь я использую термин «алгоритмы»)

На мой взгляд, алгоритмы являются абстрактными и концептуальными, чьи свойства, такие как сложность времени / пространства, не должны зависеть от того, реализованы ли они особым образом, но так ли это?


Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Жиль "ТАК - перестань быть злым"

Ответы:


42

Конечно. Безусловно. Вот как примирить ваш дискомфорт.

Когда мы анализируем время выполнения алгоритмов, мы делаем это в отношении конкретной модели вычислений . Модель вычислений определяет такие вещи, как время, необходимое для выполнения каждой базовой операции (время поиска в массиве или время?). Время работы алгоритма может зависеть от модели вычислений.O ( 1 )О(журналN)О(1)

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

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

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


Как вы сказали, мы используем модель произвольного доступа в качестве модели вычислений, но когда мы используем GPU для определенных вычислений, временная сложность для некоторых алгоритмов изменяется по мере использования инструкций SIMD.
Глубокий Джоши

6
Также обратите внимание, что обозначение O () является верхней границей. Даже если вы используете аналогию с выдвижным ящиком, нахождение выдвижного ящика ограниченного размера (реальная память ограничена в размерах) на сборку занимает O (1) времени. Даже если вам потребуется 20 минут, чтобы добраться до самого дальнего ящика (весь кэш отсутствует, и вам даже придется загружать данные из свопинга), это все равно время O (1), потому что 20 минут будут вашей скрытой константой для доступа к памяти.
Госвин фон Бредерлоу

2
О(1)О(N)

1
@CortAmmon: даже в большом массиве использование линейного поиска может быть быстрее, чем использование хэш-карты, если все, кроме нескольких элементов, которые ищут, находятся очень близко к началу. Например, если 50% элементов соответствуют первому элементу, 25% соответствуют второму, 12,5% соответствуют третьему и т. Д., За исключением того, что один нечетный элемент будет соответствовать чему-то, что может быть в любом месте массива, ожидаемое число сравнений с выполнить M поиска по списку размера N будет 2M + N.
суперкат

5
@DeepJoshi SIMD инструкции не меняют сложность алгоритмов. Они только изменяют мультипликативную константу.
Жиль "ТАК - перестань быть злым"

5

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

О(журналN)О(1)

Итак, да, аппаратное обеспечение (т. Е. Модель вычислений) действительно влияет на время работы алгоритмов, как объясняет DW , но это не то, на чем, кажется, основан ваш пример доступа к массиву.


2
Чтобы быть справедливым, вы пропустили все части между «контроллер памяти устанавливает напряжения на адресных проводах в двоичное представление семнадцати» и «данные возвращаются». Одна из этих частей почти наверняка является бинарным деревом поиска, описанным OP; но, тем не менее, он выполняется в постоянное время, потому что log n составляет приблизительно 64 для всех n .
Quuxplusone

@Quuxplusone Какая часть памяти использует бинарный поиск? Адресные строки напрямую выделяют ячейки памяти.
Дэвид Ричерби

Мы работаем далеко за пределами моей области знаний, но я хотел сказать, что декодер адресов будет реализован в виде дерева демультиплексоров . (Предполагая, что мы напрямую воздействуем на физическую память, игнорируя любые дополнительные сложности, связанные с кэшированием .) Опять же, все эти дополнительные сложности только добавляют O(lg size-of-memory), т. Е. Пренебрежимо малы - но это именно то, о чем спрашивал OP!
Quuxplusone

2

Нет, аппаратное обеспечение не влияет на сложность алгоритмов.

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

Для поиска нужного ящика (для доступа к элементу массива) используется алгоритм «открыть N-й элемент напрямую по индексу», а не алгоритм «линейный поиск» или «выполнить двоичный поиск». Алгоритмы не изменены, но выбор.

С другой стороны, сам анализ сложности, а точнее его значимость, сильно зависит от аппаратного обеспечения.

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

Или потому, что предположения, которые когда-то были верными (или в основном верными), больше не верны. Например, каждая операция в основном одинакова (только небольшие постоянные различия, которые не имеют значения), или не имеет значения, в каких местах памяти вы обращаетесь в каком порядке. Из анализа сложности можно сделать вывод, что какой-то алгоритм значительно превосходит все, потому что ему нужно только столько операций. На практике вы можете обнаружить, что каждая операция приводит к гарантированному отсутствию кэша (или, что еще хуже, к отказу страницы), который вводит k , настолько большое , что оно перестает быть незначительным, но доминирует над всем.
Если алгоритм A требует 500 операций для обработки набора данных заданного размера, а алгоритм B - только 5, но B вызывает 5 сбоев, каждый из которых сжигает двадцать миллионов циклов, то, несмотря на то, что может сказать вам анализ или здравый смысл, A лучше.

Это привело к забавным сюрпризам, таким как, например, в Cuckoo Hashing несколько лет назад. Который был значительно выше, потому что [длинный список преимуществ]. После того, как шумиха остыла, оказалось, что она значительно уступает, поскольку гарантирует два промаха кэша (ошибки для больших наборов данных) при каждом доступе.

Подобное произошло с идентификацией и обработкой подмножеств данных. Часто правильное решение в настоящее время таково : «просто сделай все» , т. Е. Вместо того, чтобы выяснить, что тебе нужно для обработки и сделать это, обработай полный набор данных линейно, даже если тебе может понадобиться только половина из этого. Потому что, хотите верьте, хотите нет, но это быстрее, потому что нет ошибок в ветвях, нет ошибок в кеше, нет ошибок страниц.
Нужно прочитать первые 8 КБ и последние 3 КБ файла размером 3 МБ? Хорошо, прочитайте весь файл и выбросьте то, что вам не нужно, потому что поиск между ними будет в десять раз медленнее, чем просто чтение всего.

Использовать карту, потому что она имеет логарифмическую сложность? Или хеш-таблица с постоянным временем доступа? Постоянные звуки потрясающие. Ну, для всего, что насчитывает менее тысячи вещей (в зависимости от аппаратного обеспечения, размера данных и схемы доступа), линейный поиск может быть таким же хорошим или лучшим. Сюрприз.

Таким образом, это касается не самих алгоритмов , а их полезности и выбора.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.