Это - копия документа, находившегося на http://dz.ru. Авторские права, если не указано иначе, принадлежат Дмитрию Завалишину и/или Евгении Завалишиной. Все изменения, внесенные мной, находятся в этой рамочке.Пожалуйста, прочитайте disclaimer. |
В свете масштабного наступления AMD на Intel как-то потускнела неприятность, которая светит им обоим. Ведь, несмотря на то, что микроархитектура Pentium Pro/II/III принципиально круче той, что была в 8086-P5, несмотря на Merced, шагнувший уж совсем далеко, несмотря на Athlon, называющий себя процессором аж седьмого поколения (не факт, что так уж обоснованно) угроза пока не снята.
Угроза со стороны весьма нетривиального подхода к построению компьютеров, подхода, потенциально способного снести с лица земли пентиумы, гексиумы и гептиумы как класс, всех вместе скопом, не вдаваясь в подробности и не делая скидок для процессоров с явным паралеллизмом, процессоров с XXL-кешом, процессоров с XXW-шиной... да что говорить - процессоров в привычном понимании этого слова вообще.
Про угрозу эту уж писано-переписано, и, конечно, не снесла всего живого с лица земли она пока не спроста. Конечно, у неё есть свои проблемы. И вот стоит их только разрешить, как сразу... Речь идёт о параллельных вычислительных системах на базе программируемых логических матриц. О системах, в которых почти что отсутствует понятие последовательно исполняемой программы. Зато присутствует понятие мешка абстрактного железа, которое путём адекватного конфигурирования может принять "форму", необходимую для вычисления согласно любому алгоритму. Или -мам. Естественно, что если у одного алгоритма не хватило силёнок задействовать всё железо системы, можно рядом строить второй и исполнять его параллельно - соответственно, нечто типа многопроцессорности такой системе присуще имманентно. Число, ясное дело, "процессоров" оказывается переменным и в "целые" процессора не очень пересчитываемым (разве что статистически), но это уж мелочи.
"Крупночь" в том, что "логико-матричные вычисления" (назовём их для краткости так, и даже ещё сократим до ЛМВ) не имеют нескольких мерзких свойств последовательных (то есть ортодоксальных) вычислительных систем. А именно - всяких узких мест типа шины, ширина и скорость которой ограничены. Поскольку сама вычислительная система имеет матричную структуру, число связей в ней соизмеримо с числом атомарных логических блоков, так что ситуации "можем посчитать, но не можем пропихнуть в шину" в ЛМВ достичь существенно, принципиально сложнее, чем традиционном процессоре. Тут линии связи - во изобилии, и шарахнуть вдоль процессора полный кадр изображения, прогоняя на нём фотошопный blur за пару тактов одновременно на каждый пиксель - не бог весть какая задача.
Операция "и", например, в обычном процессоре реализуется миллионами его транзисторов (целым процессором для 486, примерно третью его для Мерседа) за один такт работы. В ЛМВ она же реализуется десятком транзисторов - тоже за один такт, но это не треть процессора, не десятая и не сотая. Так, закоулок, огрызок без имени и отчества, один логический блок из тысяч, миллионов - уж на сколько денег хватит.
Тут подходим к масштабируемости. У ЛМВ нет и дурацкой проблемы традиционного процессора с масштабированием. Если в писюке два процессора из-за драк за шину дают не 200, а хорошо если 180% производительности одного, то в ЛМВ удвоение объёма матрицы даёт двойной же прирост - если только сумеешь загрузить всё до отказа, конечно. Опять же, с ростом вычислительной мощности приподнимается и пропускная способность - ведь матрица всегда состоит не только из логических элементов, но и из связей.
So far so good. Где же проблемы-то? Почему это чудо ещё не победило? Да, вот ерунда, там не всё просто, как вы уж догадались. Возьмём ту же обработку изображения, blur для фотошопа. Положим, мы реально захотели выполнить эту операцию. Чтобы провести её с полной вычислительной эффективностью, нужно сконфигурировать структуру матрицы под задачу - создать в ней миллионы ячеек, собранных в прямоугольный массив размера самого изображения так, чтобы "пропихивание" через этот массив изображения привело к параллельному и мгновенному исполнению над ним нужной операции. Легко? Легко. Но... долго! Ведь чтобы вгрузить в матрицу новую схему связей тоже нужно время! Ага, попались! Фокус довольно злой - теперь считать-то можно быстро, и если бы нужно было посчитать тысячу или миллион блюров мы бы последовательный процессор сделали как стоячего. Но нужен один. Ровно. Зато программа для обработки миллиона пикселей будет состоять из... миллиона инструкций, по одной на пихель. И эту программу нужно как-то прокачать через кристалл к каждой ячейке матрицы. Долго это, да и программа великовата.
Ну хорошо, этот случай прост - поскольку задача имеет регулярную структуру, можно что-нибудь придумать - например, научить матрицу вентилей дублировать схему связей вдоль и поперёк себя на нужное число ячеек. Тогда останется сформировать (грубо говоря) в матрице схему обработки одного пикселя, а потом скомандовать - размножайсь, ать-два. И скопируется одна ячейка на юг и запад в нужном количестве экземпляров. Положим даже это получится сделать за один такт.
Отлично? Отлично! За пяток тактов мы "нарисовали" обработчик одного пикселя, за такт скопировали его на миллион других, ещё за такт-два, собственно, угрызли миллион пикселей оптом. Производительность - непостижимая. Более ста тысяч пикселей в такт, а если учесть, что каждый пиксель - это взвешенная сумма окружающих, например, то есть на пиксель приходится примерно операций (команд обычного процессора) с 20, суммарная производительность порядка двух миллионов команд обычного порош... гм... процессора в такт. То есть уже для тактовой частоты в ОДИН МЕГАГЕРЦ мы получаем производительность порядка 2 000 000 MIPS (миллионов инструкций в секунду). Пентиумы III толпятся стаями у входа и курят, глядя на эту вакханалию. А мы увеличиваем тактовую частоту до 4.7 мегагерца (IBM PC XT) и получаем уже девять триллионов операций в секунду. Пентиумы III бросают курить и идут топиться, потому что повеситься им не за что - шеи нет.
Идут? Нет, что-то пока не идут. Что за беда? А просто если бы нам бы нужно было бы делать только blur и emboss, то ЛМВ бы всех победила. А нам не так часто это нужно. Увы, традиционные задачи редко имеют регулярную структуру, а значит фокус не проходит. Пока не проходит. Рук никто не опускал. Каспарова вздрючила именно параллельно-вычислительная система - правда, специализированная, но.
Интересная аналогия с динамически конфигурируемыми матричными вычислительными системами просматривается в недалёком прошлом. Многие помнят про микропрограммирование, а кое-кто им даже пользовался. Мало, кто, но есть такие.
Что за фокус? А не фокус вовсе. Просто в некоторый момент процессоры внутри себя делались по тому же принципу, что и весь компьютер. Внутри процессора сидел другой процессор, который исполнял микропрограммы. На каждую команду "большого", "настоящего" процессора "мелкий" процессор просто отрабатывал отдельную микропрограмму, которая и описывала логику отработки "большой" команды. Например, берём команду "прибавить регистр 1 к содержимому памяти по адресу 337 и положить в регистр 2". Микропрограмма на такую команду выполняла элементарные шаги - заставляла процессор выставить адрес памяти, включить режим считывания из памяти, направить считанное в арифметико-логическое устройство, подогнать туда же значение из регистра 1, просуммировать, положить результат. Всё просто.
Обычно микропрограммы были фиксированными и содержались в ПЗУ внутри процессора. Строго говоря, об их существовании программист мог и не знать. Да, как правило, и не знал. Однако не всякий и не всегда. Иным показалось, что если бы микропрограммы можно было крючить на свой лад, производительность можно было бы поднять, и преизрядно. Ну вот, к примеру, очень часто встречается у данного программиста операция a + b - c. Две команды минимум, если просто программировать. А если залезть в микропрограмму, то можно создать под себя одну специальную команду процессора, которая сразу и сложит и вычтет. Ну, не сразу, последовательно, но всяко быстрее, чем с тем же справятся две команды. Опять же и программа несколько похудеет. Сплошная польза.
Беда вот только, что неправильным микропрограммированием можно физически спалить процессор, посему в тех процессорах, которые не были на микропрограммном уровне защищены от ошибок программиста загружать свои микропрограммы дозволялось лишь ядру операционной системы. А значит, применимость методики резко ограничилась.
Это не удивительно, да и, в целом, жалеть тут нечего. От микропрограммирования процессоры давно ушли и таким способом их подгибать под свои нужды уже всяко не выйдет. А вот другим...
Не логично ли поглядев на две крайности попытаться найти золотую середину? Мы имеем два подхода. Первый, ортодоксальный - команда за командой, чисто последовательный процесс, который искусственным образом параллелизуется, чтобы уйти от ограничений, навязанных последовательной структурой программы. (Кстати, таковая структура для программы вовсе не естественна, да и не всегда ей присуща - см. тот же пролог, который элементарно параллелизуется.) Второй, нетривиальный - полностью параллельные матрично-логические системы. Они страдают от сложностей с программированием и распараллеливанием задач, а заодно и от нехватки задач истинно регулярных, легко ложащихся на методику.
Надобно объединить! Пусть процессор состоит из совокупности динамически конфигурируемых логических матриц, взываемых к жизни макрокомандами и структуризуемых микрокомандами. Тогда будет возможно состряпать под конкретную задачу нужные для её решения логические/вычислительные схемы и прогонять по ним данные мановением одной макрокоманды. Правда, от обыденных процессоров останется шина, вечное узкое место. Но, в конце концов, её же можно расширить до адекватных размеров, да и на то кеш есть, чтобы шина иногда дремала.
Интересно, не этим ли занимается сверхсекретная Трансмета. Ведь мало сделать процессор, который умеет исполнять чужие наборы команд. Нужно, чтобы он сам по себе облада какой-либо ценностью. Иначе же зачем его вообще использовать.