По закону Мура плотность транзисторов на микросхеме удваивается каждые 24 месяца. Производительность CPU, GPU, TPU и NPU растёт уже несколько десятилетий, что привело нас вплотную к задачам эмуляции мозга и Сверхинтеллекта.

Искусственный Интеллект быстро прогрессирует, превосходя человеческие возможности в разных бенчмарках (человеческий уровень принят за 0, а первый год разработки моделей за −100), источник: Kiela et al. (2023)
Искусственный Интеллект быстро прогрессирует, превосходя человеческие возможности в разных бенчмарках (человеческий уровень принят за 0, а первый год разработки моделей за −100), источник: Kiela et al. (2023)

Когда-то компьютеры занимали целые комнаты, а сегодня у каждого в кармане маленький «суперкомпьютер». Но специалисты по теории информации решают фундаментальный вопрос: сколько места (памяти) нужно в теории, чтобы выполнить задачу? Этот вопрос лежит в основе понятия вычислительной сложности.

Вычислительная сложность или просто «сложность» в информатике означает объём ресурсов для вычисления задачи. Раздел, изучающий вычислительную сложность, называется теорией сложности вычислений.

Каждый алгоритм требует определённых ресурсов для вычисления. У него есть два ресурса — время (вычислительные циклы CPU, P) и пространство (память, PSPACE). Так мы учитываем временну́ю сложность алгоритма и пространственную сложность.

Временна́я и пространственная сложность алгоритма обычно выражается с использованием математической нотации «O» большое. Например, O(n), O(n\log n), O(n^{\alpha }), O(2^{n}), где n является характеристикой входных данных, которые влияют на сложность.

Оптимизации алгоритмов для решения NP-сложных задач
Оптимизации алгоритмов для решения NP-сложных задач

Итак, у нас время и память. Но как они зависят друг от друга? Правда ли, что любая задача, которая решается в полиномиальном пространстве PSPACE, также решается в полиномиальном P? И как они могут друг друга заменять?

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

С момента публикации фундаментальной научной работы Джона Хопкрофта с соавторами «О соотношении времени и пространства» ("On Time Versus Space") 1977 года считалось, что при увеличении сложности задачи (количество шагов алгоритма) пропорционально растёт и объём необходимой памяти. Таково было интуитивно понятная зависимость.

Только недавно выяснилось, что «конвертация сложности» работает иначе. И на самом деле требуется не t памяти, а всего лишь \sqrt{t}.

P ≠ PSPACE

В теории сложности вычислений полиномиальное пространство PSPACE означает задачи, которые компьютер может решить, используя ограниченное количество памяти. Например, если с ростом сложности задачи разумно растёт и количество занимаемой памяти (n^2, n^3) — это полиномиальное пространство. Если же объём памяти растёт экспоненциально, как 2^n — не полином, и он за пределами PSPACE.

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

Вопрос в том, насколько эти два класса пересекаются. Другими словами, насколько мы можем пожертвовать памятью ради производительности — и наоборот. Каков теоретический предел, в какое минимальное «пространство» можно втиснуть вычисления заданной сложности? И как растёт потребление памяти при увеличении сложности задачи?

На протяжении 50-ти лет учёные бьются над проблемой P ≠ PSPACE. За это время они смогли доказать только то, что если задача требует t шагов, то решение возможно с использованием примерно t / \log t бит памяти. Но лишь в малом классе задач. Что будет дальше, при увеличении сложности?

Всегда предполагалось, что дальше зависимость тоже соблюдается. Грубо говоря, если задача требует в сто раз больше шагов, то она потребует в сто раз больше памяти.

Но оказалось, что логика здесь не действует. Всё работает иначе.

Неожиданное решение

В прошлом году на симпозиуме ACM по теории вычислений в Праге была официально представлена работа, которая вносит неожиданный поворот в эту задачи. Автор статьи Райан Вильямс из Массачусетского технологического института доказал, что любая задача, решаемая за время t, требует не t / \log t, а всего около \sqrt{t} бит памяти! То есть в сто раз сложнейший алгоритм можно решить, увеличив объём памяти всего в десять раз! Это стало ошеломительным открытием для индустрии.

«Этот результат показывает, что интуитивный подход совершенно неверный, — сказал Уильямс в комментарии журналу Quanta Magazine. — Я сначала даже подумал, что-то неправильно [в моём доказательстве], потому что вывод совершенно неожиданный».

Решение Уильямса основано на редукции — преобразовании одной задачи в другую, которая на первый взгляд кажется не связанной с изначальной задачей, но на самом деле они полностью математически эквивалентна ей. Решение одной задачи напрямую решает другую. Эта идея лежит в основе работы Уильямса: любую задачу можно преобразовать в такую, которую можно решить, умело повторно используя пространство, втиснув необходимую информацию всего лишь в квадратный корень от количества бит. Таким образом, исходная проблема решается в этом компактном контейнере.

«Такой прогресс невероятен, — говорит Махди Черагчи (Mahdi Cheraghchi) из Университета Мичигана. — Раньше были задачи, решаемые за определённое время, но многие считали, что это нельзя сделать в столь крошечном пространстве».

Доказательство

Предположение P ≠ PSPACE требует доказать, что в линейном пространстве существует задача, которую невозможно решить за время O(n^k) для любого постоянного k\geq1.

Требуется показать, что существует задача линейного пространства, которую нельзя решить за O(n^k) времени для любого постоянного k\geq1.

В статье Уильямса делается важный шаг к разделению P и PSPACE, потому что он доказал, что существуют задачи, которые можно решить в O(n) пространства, но невозможно решить за время n^2/{\log^c}n для некоторого постоянного c \textgreater 0.

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

Более формально, пусть TIME[t(n)] будет классом задач принятия решений, решаемых многоленточными машинами Тьюринга за время O(t(n)), а SPACE[s(n)] — классом задач, решаемых ими же в памяти O(s(n)).

Далее автор доказывает теорему, что для любой функции t(n) \geq n выполняется правило:

TIME[t(n)] ⊆  SPACE[\sqrt{t(n) \log t(n)}]

Для доказательства этой теоремы автор использует хитрую структуру в виде дерева вычислений (Tree Evaluation), а именно — недавно открытый свежий алгоритм для этого дерева.

Вот доказательство по шагам:

  1. Разбиваем работу многоленточной машины Тьюринга на блоки по b шагов, а ленты — на блоки по b ячеек.

  2. Строим абстрактное дерево вычисления. Каждый узел дерева соответствует тому, что происходит с некоторым блоком ленты за b шагов. Дети каждого узла — предыдущие блоки, от состояния которых он зависит.

  3. Получается задача вида Tree Evaluation. Каждая внутренняя вершина дерева — это функция от значения детей, а листья — исходные данные. Нам нужно узнать значение в корне.

  4. Тут самое главное, с точки зрения вычисления. Автор использует опубликованный в 2012 году алгоритм Кука–Мерца для Tree Evaluation, который умеет считать значение в корне в очень маленькой памяти:

O(d⋅b+h \log⁡(d⋅b))

где h — высота дерева, b — размер значения в узле, d — число детей узла.

Подбирая длину блока b, то есть балансируя высоту дерева и размер значений, автор получает как раз значение используемой памяти примерно \sqrt{t \log t}.

Таким образом, любой алгоритм из t шагов на многоленточной машине Тьюринга можно симулировать, используя всего \sqrt{t} памяти, точнее, O(\sqrt{t \log t}).

Как говорилось в известной книге «Programming Perl»: «Если у вас кончилась память, её можно докупить, но если кончилось время — у вас проблема» (в вольном переводе).

За работы по нижним оценкам вычисляемости алгоритмов Райан Уильямс получил премию Гёделя 2024 года, есть видеозапись лекции на церемонии в Таллине, где он рассказывает о своих исследованиях (с 18-й минуты). Вышеупомянутая статья Уильямса «Симуляция времени в квадратном корне пространства» 2025 года непосредственно вытекает из этих исследований:

Эффективность использования памяти

По мнению специалистов, благодаря этому прорыву полностью меняется наше теоретическое понимание эффективности компьютеров. Как выясняется, настоящим ограничением является не объём памяти, а эффективность её использования.

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

  • MicroQuickJS от Фабриса Беллара — движок JavaScript для встроенных систем. Он компилирует и выполняет программы на JavaScript, используя всего 10 КБ оперативной памяти. В ПЗУ движок с библиотекой на С занимает 100 КБ (код ARM Thumb-2). При этом скорость компиляции и выполнения кода сопоставима с QuickJS, это предыдущая разработка Фабриса Беллара, тоже минималистичный JS-движок, для x86 систем: только файлы С, никаких зависимостей: демо, бенчмарки 1 и 2.

Сравнение производительности движков JavaScript
Сравнение производительности движков JavaScript

Эти примеры показывают, что сложные вычислительные задачи действительно можно упаковать в минимальное количество памяти.


Научная статья «Симуляция времени в квадратном корне пространства» («Simulating Time With Square-Root Space») опубликована 25 февраля 2025 года к симпозиуму ACM по теории вычислений в Праге (arXiv:2502.17779).

© 2026 ООО «МТ ФИНАНС»

Комментарии (13)


  1. VladimirFarshatov
    18.03.2026 13:20

    Хорошая статья, автор ожидает что она зайдет сайтописателям ожиревших сайтов? Ну почему я сомневаюсь? )))


  1. misha_erementchouk
    18.03.2026 13:20

    А что это означает для высокоуровневой организации вычислений? Возьмем сортировку слиянием с временной сложностью O(N log N) и пространственной сложностью O(N). Разве не странно ожидать, что из теоремы следует, что существует алгоритм сортировки с пространственной сложностьюO(\sqrt{N \log N})?


    1. janatem
      18.03.2026 13:20

      Пример с сортировкой не совсем удачный — там размер аргумента (и результата) большой по сравнению с дополнительной памятью, которой там всего O(1). Вообще для алгоритмов окололинейной сложности эта теорема, кажется, не очень интересна.


      1. misha_erementchouk
        18.03.2026 13:20

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

        И все равно непонятен вот этот кусочек из заметки

        доказал, что любая задача, решаемая за время t, требует не t / \log t, а всего около \sqrt{t} бит памяти! То есть в сто раз сложнейший алгоритм можно решить, увеличив объём памяти всего в десять раз! Это стало ошеломительным открытием для индустрии.

        Особенно в контексте рассуждения об эффективности использования памяти.


        1. janatem
          18.03.2026 13:20

          Согласно определению сложности, за N берется размер входного аргумента. Тогда временна́я и пространственная сложность — функции от именного этого N. В случае сортировки N — это размер массива (точнее, N, умноженное на размер элемента в битах). Наивный алгоритм бы взял еще столько же памяти, всё равно бы вышло O(N), что по порядку величины не отличается от умного алгоритма, который бы брал O(1) дополнительной памяти.


          1. misha_erementchouk
            18.03.2026 13:20

            Я думал, что можно придумать пример сортировочно-навеянной задачи, которую легко навесить на сортировку слиянием с сохранением O(N log N) и O(N), но которая заставит завести копию сортируемого массива и потому ни о каких O(\sqrt(N ...)) речи, вроде как, быть не может. Но, по-видимому, так не получится. Например, та же задача о четности сортирующей перестановки элементарно решается с дополнительной памятью O(1) с помощью пузырька.


    1. rdmit
      18.03.2026 13:20

      Пространственная сложность будет

      O(N\sqrt{NlogN})


      1. misha_erementchouk
        18.03.2026 13:20

        А как такой результат получается? Выходит стандартная оценка пространственной сложности сортировки слиянием - обман трудящихся?


      1. janatem
        18.03.2026 13:20

        Почему? В самой наивной версии достаточно 2N — просто заводим вспомогательный массив того же размера. Но, насколько я понимаю, можно обойтись и кусочком фиксированного размера, тогда N+O(1).


    1. ant3mc
      18.03.2026 13:20

      Обычная сортировка слиянием не in-place, и поэтому действительно имеет пространственную сложность( требует дополнительной памяти) O(n) .
      Однако , тут (думаю), речь о другом. Ведь мы (при желании) можем создать алгоритм сортировки , который потребует дополнительной памяти в n*n раз больше, чем времени .
      Авторы говорят (я предполагаю) о решении алгоритмической задачи, а не о конкретном алгоритме. Есть задача (к примеру- отсортировать массив чисел). И обязательно существует (но. возможно, ещё не найден) алгоритм, который требует дополнительной памяти всего лишь корень квадратный от времени.


      1. misha_erementchouk
        18.03.2026 13:20

        Да, похоже, что из задачи сортировки интересного примера не получается. Всегда можно остортировать in-place, скажем, элементарно через поиск максимальных элементов, с дополнительной памятью O(1).


  1. renakdup
    18.03.2026 13:20

    Сложные вычисления без тонны RAM, а JS-рантайм - держи 2 ГБ на пустом hello world 8-(


  1. MagisterAlexandr
    18.03.2026 13:20

    было интуитивно понятная зависимость

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