Последовательные и параллельные миры
(http://www.eejournal.com/archives/articles/20170124-parallel-universe/).
Реальные вызовы в мире компьютеров следующего поколения.
http://www.eejournal.com/archives/articles/20170124-parallel-universe/
by Kevin Morris
Обозреватель сайта eejournal Кевин Морис о перспективах развития компьютерных архитектур.
На даный момент сложились два альтернативных вида множеств вычислений: мир последовательных вычислений — так воспринимает алгоритмы наш мозг, и мир параллельных вычислений — так на самом деле работает вычислительная аппаратура. Эти два мира всегда сосуществуют, но архитектура фон Нэймана нас закрывает от них. Так как наши процессорные архитектуры основаны на счетчиках команд, ми до сих пор уверены, что наши компьютеры исполняют только по одной команде за раз.
Поэтому, когда мы пишем свои программы, -даже языком высокого уровня — мы всегда имеем в виду, что каждое действие должно выполняться в нашем алгоритме за предыдущим действием. Как инженеры-электронщики, мы должны понимать, что на самом деле у нас есть параллельное компьютерное железо, предназначенное выполнять много заданий одновременно. Это необходимо для того, чтобы мы подходили осознано и организовано к разработке своих алгоритмов.
Даже тогда, когда начали осваивать языки описания аппаратуры, программа на таком языке воспринимается как последовательность. Хотя правило, что одна команда выполняется в один промежуток времени, не действует при разработке аппаратуры. Как результат, VHDL и Verilog до сих пор есть языками, которые почти не возможно понять и использовать, в отличие от нормальных высокоуровневых языков программирования. На самом деле это очень плохо. Если бы программисты писали программы на языках VHDL и Verilog так же уверенно, как они это делают на C, то ПЛИС-ы (либо что-то подобное) были бы уже внедрены намного глубже в серъёзные вычисления.
Распространение объектно-ориентированного программирования (ООП) немного разбило стену между этими последовательным и параллельным мирами. Само понятие объекта со своими собственными методамы и отдельным пространством данных, много в чем не сходится с идеей единого программного потока в процессоре, в котором одновременно исполняется только одна команда. Считается, что объекты существуют и обрабатываются в процессоре параллельно.
Компиляция объектно-ориентированого кода вниз до какой-то машинной программы, выполнение которой моделируется так, будто объекты выполняются параллельно, это большое достижение объектно-ориентированых компиляторов. И всё же, ООП пробило дыру в барьере между последовательной вселенной — где мы исторически реализуем алгоритмы, составленные для процедурных моделей программирования — и параллельной вселенной, где миллионы логических вентилей переключаются между двумя логическими состояниями почти одновременно.
Теперь, однако, мы сталкиваемся с противоположной проблемой объектно-ориентированого программирования. Если раньше ООП пыталось отобразить параллельные концепции в последовательное аппаратное обеспечение, то теперь нам необходимо отображать алгоритмы, которые были задуманы как последовательные, в очень оптимизированные параллельные аппаратные структуры. Если мы сможем это сделать, то можно будет взять последовательный программный код унаследованного программного обеспечения и автоматически транслировать его в специализированное аппаратное оборудование.
Награда за такой успех была бы впечатляющей — производительность вычислений выросла бы в сотни раз и особенно — параметр производительность на ватт потребляемой мощности, что не зависит от улучшения базовой технологии полупроводников.
Когда мы представляем себе алгоритм как набор команд, выполняющихся последовательно, мы, как правило, игнорируем возможности для распараллеливания и конвейеризации. Это особенность человеческого сознания — организовать какой-то сложный процесс как последовательность простых действий. И совсем не возникает мысли что-то распараллелить. Разве что повар выпекает все печеньки параллельно на одном протвене.
И такое же отношение к алгоритмам перекладывается на программирование. А распараллеливающий компилятор часто не в состоянии распознать, какие простые действия можно выполнить параллельно, а какие — нет. Следовательно, приоритетным заданием должно быть создание таких инструментов, которые могут автоматически преобразовывать последовательные алгоритмы в оптимизированные параллельные структуры. Инструменты должны быть в состоянии определить зависимости по данным и порядок операций, с целью создать параллельную модель вычислений.
Остаётся открытым вопрос о выборе и использовании вычислительных ресурсов. Большее или меньшее количество ресурсов будет определять объём и типы вычислений, которые мы могли бы распараллелить, а так же — эффективность использования ресурсов.
В мире аппаратных средств ресурсы не бесконечны, то есть аппаратный алгоритм может просто не поместиться. (В отличие от однопроцессорной системы, где алгоритм может исполняться как последовательность миллиардов и триллионов команд — здесь ресурсы времени почти бесконечны.) Если у нас есть операция умножения внутри цикла и этот цикл исполняется один миллион раз, это значит, что операции умножения можно выполнять параллельно в аппаратных блоках умножения на нашем чипе. Но, наверное, это будет не миллион блоков умножения.
Наш новый инструмент должен понимать наличные ресурсы при принятии решения о степени параллельности реализации алгоритма. Он должен выбрать в данном случае, например, сто или тысячу блоков умножения. Кроме того, эти ресурсы, наверное, должны быть организованы как конвейеры с целью максимальной их загрузки и увеличения пропускной способности. Конечно же, к проблеме пропускной способности добавляется проблема латентной задержки.
Итак, понятие простой компиляции программы, как для прямой реализации в машине фон Нэймана, существенно изменяется. Теперь, чтобы скомпилировать устаревшее (последовательное) программное обеспечение для параллельной архитектуры, необходимо тщательно проанализировать его для выявления информации о возможности параллельных вычислений, которая не была там явно задана. При этом пространство возможных реализаций такой программы экспоненциально увеличивается с ростом степени параллелизма. И это только то, что видно на поверхности проблемы. Распараллеливание, которое рассматривалось выше, касается алгоритмов без условных операторов. А алгоритмы с условными переходами значительно тяжелее анализировать и распараллеливать.
Сегодня оптимизация аппаратной реализации последовательного программного обеспечения — это область исследований инструментов высокоуровневого синтеза. Технология таких инструментов прошла долгий путь за последние три десятилетия. Но она до сих пор далека от цели — автоматической трансляции устаревших программных приложений в реконфигурированные гетерогенные вычислительные машины, которые включают в себя как процессоры фон Нэймана, так и альтернативные аппаратные архитектуры, такие как ПЛИС. Создание такого инструмента — это невероятно сложное дело, оно способно революционизировать вычисления. Будем же надеяться, что нашим коллегам, решающим эту проблему, дует в спины попутный ветер!