В первые годы развития авиации было очевидно, что скорости самолетов будут только расти. Так, собственно, и произошло: от смешных 50 километров в час для самолета братьев Райт в 1903 году мы пришли к 800-900 км/ч для различных Boeing и Туполевых в середине 1960-ых. И с тех пор рост скорости коммерческих самолетов застопорился: да, были попытки создания сверхзвуковых пассажирских самолетов, и Конкорды вместе с Ту-144 даже летали около двух десятилетий. Но из-за не самой высокой безопасности, а главное неэффективности с точки зрения траты энергии при столь высоких скоростях, мы на данный момент тратим на путешествия по воздуху столько же времени, сколько и наши родители 50 лет назад.
Да, на бумаге все хорошо: от 40-нанометровых процессоров в конце нулевых мы перешли к 7-нанометровым решениям, а в конце этого года нам обещают уже 5 нм. Однако стоит понимать, что эти нанометры — мнимые, и достигаются они благодаря трехмерному расположению транзисторов и прочим хитростям. На деле ключевые части транзисторов, такие как затвор, за последние 10 лет уменьшились лишь на несколько десятков процентов. И именно поэтому современные 14-нанометровые процессоры от Intel выступают не особо хуже 7-нанометровых решений AMD, хотя на деле разница должна быть близка к двукратной.
Красивая табличка, демонстрирующая рост эффективности процессоров при переходе на более тонкие техпроцессы. Увы, она уже не выполняется.
И это проблема. Представим на минуту, что закон Мура прекратил работать 20 лет назад. Мы жили бы в мире, где процессоры в десятки раз слабее тех, что мы имеем на самом деле. У нас не было бы смартфонов с их компьютерными возможностями — мы бы пользовались телефонами с базовым функционалом типа звонков и сообщений. У нас не было бы потокового видео — процессоры просто не вытянули бы его. Это же касается и красивейших современных игр и многого другого. Даже интернет был бы в виде простых текстовых сайтов с редкими картинками. Поэтому легко представить, какие инновации мы можем пропустить через те же 20 лет, если не сможем продолжать повышать производительность вычислений теми же темпами.
В последние годы исследователи ломают голову над тем, что делать дальше. Разумеется, есть надежда, что ответ — это новые технологии, такие как квантовые вычисления, углеродные нанотрубки или фотонные вычисления. Проблема тут лишь в том, что это пока очень размытые технологии, которые в лучшем случае работают в лабораториях, и до полок в магазине доберутся они еще очень нескоро. Поэтому не стоит надеяться на быстрое и полное переосмысление компьютерных чипов — имеет смысл серьезно изменить подход к написанию программного обеспечения для текущих.
Чарльз Лейзерсон, профессор компьютерных наук и инженерии в MIT, отметил в своей последней статье на Science, что в течение многих лет программистам не приходилось беспокоиться о том, чтобы заставить код работать быстрее, потому что закон Мура делал это для них. Поэтому они выбрали простой путь, отдавая приоритет своей способности быстро писать код над способностью компьютеров выполнять этот код как можно быстрее.
Хорошо заметно, что последние годы рост замедлился.
Например, многие разработчики используют такие методы, как «редукция»: берется код, который решает задачу А, и используется для решения задачи Б, даже если это неэффективный способ ее выполнения. Предположим, вы хотите построить систему, подобную Siri, чтобы отвечать на голосовые команды «да» или «нет». Вместо того чтобы создавать специальную программу для этого, вы можете использовать существующую программу, которая имеет широкий спектр всевозможных ответов — ту же Siri — и настроить ее так, чтобы она отвечала на вопросы только «да» или «нет».
Хорошая новость заключается в том, что этот подход помогает вам писать код быстрее. Плохая же новость в том, что иногда это приводит к ошеломляющей неэффективности, которая может очень быстро усугубиться. Если в вашей программе одна такая редукция, то ее влияние на общую производительность может быть и незаметно. Но если вы пишете программу с двадцатью уровнями редукции, код может быть в сотню раз менее эффективным, чем мог быть, если бы вы писали «честно».
И это не просто мысленный эксперимент. Возможность добиться дальнейшего прогресса в таких областях, как машинное обучение, робототехника и виртуальная реальность потребует огромных вычислительных мощностей. Если мы хотим использовать весь потенциал этих технологий, то должны внести значительные изменения в принципы работы с кодом. Наилучшим способом является создание новых, заточенных под определенные задачи инструкций процессоров и соответствующих программных алгоритмов, однако это дорого и в конечном счете может привести к тем же редукциям с теми же последствиями. Поэтому для большинства компаний наиболее практичным способом повышения производительности вычислений является повышение эффективности уже имеющегося программного обеспечения.
Современные процессоры имеют огромное количество инструкций, но далеко не весь софт ими пользуется.
Одна из стратегий повышения производительности заключается в распараллеливании кода. Достаточное количество существующих программ были разработаны с использованием алгоритмов десятилетней давности и нередко не используют современные инструкции типа AVX. Более того, если ПО в целом уже научилось работать с многоядерными CPU, то части программ все еще могут быть «одноядерными», причем это касается даже таких известных утилит, как Photoshop. Поэтому распараллеливание и использование современных инструкций может позволить ускорить выполнение некоторых сложных задач в десятки и даже сотню раз, или же можно пойти другим путем и делать все с той же скоростью, но гораздо энергоэффективнее.
Однако на этом благом пути по оптимизации производительности будут встречаться и чисто земные проблемы. Во-первых, никто не отменял «индусский код», в котором исправление одной проблемы тянет за собой ворох новых, и в итоге зачастую проще, но отнюдь не дешевле, переписать программу с нуля. А заниматься этим в случае с тяжелым современным софтом хотят и могут далеко не все компании. Во-вторых, существует понятие институциональной инерцией, когда программисты (и не только) продолжают делать все так, как привыкли, неохотно переходя к более новым вещам.
Классический пример индусского кода, для понимания которого не нужно быть программистом.
Развитые технологические гиганты, такие как Google и Amazon, уже поняли цену оптимизаций. Огромный масштаб их центров обработки данных означает, что даже небольшие улучшения в производительности программного обеспечения могут принести большую финансовую отдачу. И, по-хорошему, по этому же пути должен пойти остальной мир — разработчики приложений больше не должны игнорировать эффективность при развертывании новых функций.
«Инженерия производительности» будет более рискованной, чем даже разработка новых кремниевых чипов. Компании изначально не могут предсказать величину ускорения своего софта, пока программисты не потратят время на оптимизацию кода. Причем где-то эффект будет значительным и оправданным, а где-то прирост производительности будет всего несколько процентов. Но по мере того, как мы достигаем физических пределов микропроцессоров, сосредоточение внимания на улучшении программного обеспечения окажется для большинства программистов лучшим вариантом получения большей отдачи от существующих компьютеров.
Разумеется, стоит понимать, что это не поможет кремниевым чипам вечно править балом — рано или поздно цена за получение лишнего процента производительности при оптимизации софта станет слишком высока. Но, по крайней мере, это вполне может позволить софту еще несколько лет становиться быстрее на том же «железе», чего вполне может хватить для разработки и выведения на рынок абсолютно новых компьютеров.