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

О случайной сложности систем поставок

Ведущие современные поставщики программного обеспечения для цепей поставок (ERP, WMS, MRP и т. д.) с трудом поддерживают даже 1 запрос в секунду на своем API-бэкенде. В Lokad мы ежедневно сталкиваемся с такими ужасными показателями производительности, так как мы на передовой в процессе извлечения данных. Для десятка клиентов или около того первоначальное извлечение данных занимало почти месяц2. Медлительность различных API является причиной 99,9% проблемы. Систем, способных поддерживать скорость 1 МБ/сек для извлечения данных, очень мало. Систем, которые не заставляют нас бессмысленно повторно извлекать одни и те же данные снова и снова, чтобы достичь самых свежих частей, еще меньше. У этих систем обычно есть в 100 и более раз больше вычислительных ресурсов по сравнению с тем, что было 2 десятилетия назад, и тем не менее они не являются фундаментально быстрее3 и не делают вещи радикально лучше. Некоторые из наиболее прогрессивных поставщиков, использующих вычисления в оперативной памяти, требуют нескольких терабайт оперативной памяти для работы с розничными сетями, что является ужасно большим4 объемом памяти, учитывая то, что делается с этими ресурсами.

Эта “случайная сложность” многих (или большинства?) систем поставок можно свести к двум основным причинам: неверным ожиданиям относительно прогресса вычислительного оборудования самого по себе и недостатку заботы о внутреннем проектировании решения.

Что касается прогресса вычислительного оборудования, до десятилетия назад не было ни одной (большой) компании, где первый закон Мура не был бы упомянут десятки раз (обычно неверно). Было ощущение, что компьютеры все время становятся невероятно быстрее. К сожалению, это прекратилось быть тривиально верным с начала 2000-х годов. Эта неверная перспектива бесконечного прогресса привела к массовым ошибкам многих программных компаний, далеко за пределами мира цепей поставок. Многие из проблем, связанных с Windows Vista (выпущенной в 2006 году), можно было отследить до первоначальных ожиданий - еще в 2001 году, когда была выпущена Windows XP - инженеров Microsoft, что процессоры будут работать на частоте 6 ГГц к 2006 году. Мы приближаемся к концу 2020 года, и игровые процессоры высокого класса едва достигают 5 ГГц. Вычислительное оборудование никогда не переставало развиваться, однако оно просто перестало развиваться тривиальным образом, по крайней мере, что касается программных компаний.

Вернувшись в 1980-е и 1990-е годы, как только программное обеспечение начинало работать, даже если оно было немного медленным на момент выпуска, было ясно, что в следующем году его скорость будет приемлемой, а через год или два - отличной. Агрессивные компании, такие как Microsoft, очень хорошо использовали эту карту: их инженерам предоставляли (и по-прежнему предоставляют) лучшее вычислительное оборудование, которое можно купить за деньги, и они систематически доводили производительность программного обеспечения до предела того, что оставалось приемлемым, зная, что аппаратное обеспечение в основном решит проблему производительности через год или два. После провала с Windows Vista, команды инженеров в Microsoft осознали масштаб проблемы и изменили свои подходы - Windows 7 стала значительным улучшением. Однако потребовалось десятилетие, чтобы Windows действительно восстановилась в плане производительности. В настоящее время прогнозы практически полностью противоположны: лучшие команды Microsoft больше не полагаются на будущее аппаратное обеспечение и почти исключительно сосредотачиваются на достижении мгновенной превосходной производительности с помощью превосходного программного обеспечения5.

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

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

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

Одна из проблем современного программного обеспечения (не только предприятий) - это избыток уровней. Данные копируются, передаются, объединяются, синхронизируются… через десятки внутренних уровней внутри программного обеспечения. В результате основная часть вычислительных ресурсов тратится на работу с “внутренней сантехникой”, которая сама по себе не приносит никакой добавленной стоимости. С точки зрения проектирования, устранение этой проблемы просто в плане концепции, но сложно в исполнении: необходимо экономно использовать компоненты сторонних производителей, особенно те, которые включают какой-либо уровень7. С точки зрения поставщика программного обеспечения, добавление еще одного уровня - самый быстрый способ добавить больше “крутых функций” в продукт, не обращая внимания на нагромождение.

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

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

Опять же, в Lokad мы выбрали полностью взаимоиспользуемую инфраструктуру. Такой подход снижает наши затраты на облачные вычисления, обеспечивая при этом производительность, которая иначе была бы экономически невыгодной (стоимость облачных вычислений превысила бы выгоду от управления цепочкой поставок). Чтобы обеспечить плавную организацию всех рабочих нагрузок, мы разработали высокую степень “предсказуемости” для нашего собственного использования вычислительных ресурсов. Язык программирования Lokad’s DSL (специфичный для предметной области), называемый Envision, был разработан для поддержки этого проекта. Вот почему целые классы программных конструкций, такие как произвольные циклы, отсутствуют в Envision: эти конструкции несовместимы с требованиями “высокой предсказуемости”, которые включает анализ данных цепочки поставок.

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


  1. В 2012 году я опубликовал проект с открытым исходным кодом ReceiptStream, чтобы продемонстрировать, что хранение истории транзакций Walmart на уровне корзины в течение примерно года не только возможно, но и может быть реализовано всего несколькими сотнями строк кода. ↩︎

  2. Мы стараемся выполнять инкрементное получение данных, если системы позволяют нам это сделать. Однако, начальное получение данных обычно охватывает период в 3-5 лет, так как наличие некоторой исторической глубины действительно помогает при анализе сезонности. ↩︎

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

  4. Я не говорю, что терабайты оперативной памяти не могут быть полезны при оптимизации цепочки поставок - повторяя вымышленную цитату, неправильно приписанную Биллу Гейтсу, что “640К должно хватить для любого”. Мой посыл в том, что неразумное использование вычислительных ресурсов - это упущенная возможность использовать их более эффективно. На декабрь 2020 года я не вижу никакой причины, почему для такого объема памяти требуется учитывать (отсутствие) сложность числовых рецептов, связанных с так называемой парадигмой “в памяти”. ↩︎

  5. Улучшения производительности, почти исключительно программные, внесенные .NET Core 1, .NET Core 2, .NET Core 3 и .NET 5, являются примером в этом отношении. Некоторые ускорения основаны на SIMD-инструкциях (одна инструкция, множественные данные), однако эти инструкции трудно можно назвать “будущим” оборудованием, так как большинство продаваемых процессоров в последнее десятилетие уже обладают такими возможностями. ↩︎

  6. Уязвимости аппаратного обеспечения, такие как Meltdown, оказались негативно влияющими на производительность существующего вычислительного оборудования. В будущем можно ожидать появления еще большего числа подобных проблем. ↩︎

  7. Слои могут иметь различные формы и типы. Docker, HDFS, Python, NumPy, Pandas, TensorFlow, Postgres, Jupyter… все они являются компонентами основного интереса, и каждый из этих компонентов вводит свой собственный программный слой. ↩︎

  8. Когда я начал работу над Lokad в 2008 году, я решил создать свой собственный прогнозный движок. Однако в то время популярностью пользовались R. В 2012 году это был Hadoop. В 2014 году - Python и SciPy. В 2016 году - Scikit. В 2018 году - TensorFlow. В 2020 году - Julia. ↩︎

  9. Испытание на прочность для определения того, использует ли предполагаемый SaaS (программное обеспечение как услуга) мультиарендную архитектуру, заключается в проверке возможности зарегистрироваться для получения бесплатной учетной записи какого-либо вида. Если поставщик не может предоставить бесплатную учетную запись, то с большой вероятностью можно сказать, что поставщик просто предоставляет ASP (поставщик услуг приложений), а не SaaS. ↩︎