Так может, повыкидывать из процессора все эти хитрые декодеры и планировщики и оставить только самое необходимое - исполнительные блоки, набор регистров, подсистему памяти и минимальный набор обслуживающей логики? Зачем, к примеру, заниматься хитроумным переименованием регистров, если этих самых регистров можно понаделать сотню-другую? И зачем отслеживать зависимости инструкций, если можно писать программы так, чтобы эти зависимости никогда не нарушались? Проще говоря, коли наш суперскалярный OoO-CPU все равно в конечном счете работает не с исходным программным кодом, а с неким внутренним его представлением - не лучше ли сразу записывать программы в этом представлении, обходясь без посредников? «В очередном такте исполнительному устройству X- загрузить из оперативной памяти по адресу из регистра такого-то данные и сохранить их в регистр такой-то; исполнительному устройству Y - взять данные из регистров такого-то и такого-то, сложить их и записать результат в регистр такой-то; устройству Z - проверить регистр такой-то на выполнение условия и по результатам проверки подкрутить внутренний указатель такой-то и сбросить при необходимости конвейер». Получится одна очень длинная инструкция (Very Long Instruction Word, VLIW), полностью и исчерпывающе описывающая, что каждому из блоков процессора следует в очередном такте делать.
К чему мы тогда придем? Получится архитектурно очень простой процессор, который будет очень трудно программировать: ведь придется детально учитывать его внутреннее устройство и особенности. Но если мы научимся это делать, то в качестве компенсации получим возможность изготовить сколь угодно навороченный CPU малой кровью - без всяких сверхсложных декодеров и планировщиков на три-четыре инструкции. К примеру, в отечественной разработке «Эльбрус Е2K» предполагалось одновременное исполнение до 24 инструкций за такт - при сохранении приемлемой сложность CPU. Реализовать что-либо подобное в классическом суперскалярном процессоре - нельзя; а при VLIW-подходе, не ограниченном жесткими рамками скоростного декодирования и планирования программы, - можно. Ведь никто же нам не запретит компилировать и оптимизировать программу хоть часами, хоть сутками - лишь бы потом она быстро исполнялась?
Единственная очевидная загвоздка в подобном подходе - тот самый компилятор, умеющий генерировать очень сложный технически и требующий тщательнейшей оптимизации машинный код для VLIW-процессоров. Но ведь, в конце концов, и простые компиляторы с языков высокого уровня когда-то казались чудом, а сейчас мы преспокойно используем сложнейшие компиляторы C++, работающие с парадигмами обобщенного программирования. Так что создание совершенного оптимизирующего компилятора для VLIW-процессоров - это, скорее, вопрос времени[Отрадно, кстати, сознавать, что над созданием этих «суперкомпиляторов», в первую очередь - Intel C/C++ Compiler, активно работают наши соотечественники - например, Нижегородская лаборатория (бывшая московская команда Бориса Бабаяна, разрабатывавшая компиляторы для «Эльбруса Е2К»). Нам бы, правда, к этому еще и свои процессоры с компиляторами…]. Но есть и другие проблемы.
Проблема первая - жесткая привязка исполняемого кода к конкретному процессору. x86-программа запросто может работать и на i386, и на Pentium 4; с каноническим VLIW-процессором такой фокус, увы, не пройдет. Правда, Intel в усовершенствованной версии VLIW-архитектуры (EPIC - Explicitly Parallel Instruction Computer, компьютер с явно заданным параллелизмом команд) смягчила этот недостаток, введя не инструкции, а bundles - эдакие «полуинструкции», упакованные в контейнере с информацией о взаимозависимостях между этим и другими бандлами. Предполагается, что процессор, без труда проверив бандлы на взаимозависимость, может запускать их параллельно и, таким образом, обладать некоторой «свободой действий» в проектировании будущих CPU, сохраняющих бинарную совместимость с текущим поколением.
Вторая проблема прямо вытекает из первой: довольно трудно сделать совместимые VLIW-процессоры, предназначенные для разных секторов рынка. Уж больно сильно привязан программный код к аппаратной начинке. То есть если мы делаем «супер-VLIW», с кучей исполнительных устройств и тщательно вылизанной подсистемой памяти - то ровно такой же «суперпроцессор» (с суперсебестоимостью) нам придется продавать и для low-end-сектора рынка. И наоборот, «сэкономив» и выкатив процессор для low-end и middle-end, мы получим крепкого середнячка, но не лидера производительности. Подход EPIC с его бандлами слегка исправляет ситуацию, но не до конца - дешевых Itanium в природе так и не появилось.