6. Помехи

Помеха определяется структурой или применением конвейера и пре­пятствует его работе с максимальной скоростью, которую можно было бы обеспечить при синхронизации ступеней конвейера. Имеются две общие категории помех: структурные и зависящие от данных. Структурные по­мехи возникают тогда, когда два различных фрагмента данных пытаются использовать одну и ту же ступень одновременно. По очевидным причи­нам такие случаи называются столкновениями. При проектировании любых конвейеров, кроме простейших,следует на самой ранней стадии разработ­ки принимать во внимание такие помехи.

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

7. Исторический обзор

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

Одной из самых ранних машин, в которой применена некоторая форма перекрытия, была машина UNIVAC 1. В ней перекрывались исполнение программы и, с некоторыми ограничениями, исполнение операций ввода-вывода. В последующих машинах этот способ был усовершенствован, так что сегодня уже не является чем-то необычным наличие в вычислительной сис­теме нескольких процессоров, целиком выполняющих функции ввода-вывода.

Использование конвейеризации и перекрытия внутри самого вычисли­тельного блока началось с применения способов, обеспечивающих ускоре­ние выборки команд. Система IBM 7094 имела память с 72-разрядными словами при 36-разрядных командах. Каждый раз при обращении к памя­ти для выборки команды не использовались 36 разрядов. Это исключало половину выборок команд для программы в виде последовательности из 36-разрядных команд.

В таких машинах, как IBM 7094 II, сделан дальнейший шаг — использо­вано расслоение памяти для ускорения обращения к ней. В расслоенной памяти несколько различных модулей работают циклически по мере то­го, как задаются обращения к последовательным ячейкам. Например, в 4-кратно расслоенной памяти все ячейки с адресами вида 4i находятся в одном модуле, с адресами вида 4i + 1 — в другом, с адресами 4i + 2 - в третьем и с адресами 4i + 3 — в остающемся модуле. Память с такой орга­низацией можно рассматривать как 4-ступенчатый конвейер, в котором в период времени, требующийся для одного обращения к памяти, до четырех различных обращений могут находиться в разных стадиях выполнения.

Разбиение самого процесса исполнения команды впервые применено в машинах STRETCH и LARC. Целью разработки машины STRETCH было 100-кратное повышение быстродействия по сравнению с более старой моделью 704, в то время как технологическая база постро­ения памяти обеспечивала 6-кратное ускорение, а технологическая база построения логических схем — 10-кратное. Остальной прирост производи­тельности должен был произойти за счет сильного расслоения памяти, сопро­вождаемого разбиением процесса исполнения команды на две фазы: выбор­ки/декодирования команды и выполнения операции над данными. В машине LARC такое разбиение было продолжено, и процесс состоял из четырех ступеней: выборки команды, выполнения индексных операций над адре­сом, выборки данных и исполнения команды.

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

Вычислительные машины семейства 6000 фирмы CDC были среди первых, в которых предпринята попытка решить проблему приостанова из-за указанной зависимости. Хотя они не были конвейерными в стро­гом смысле, многие из использованных в них способов были предвестника­ми более новых подходов, примененных уже в конвейерных машинах. На­пример, архитектура набора команд была спроектирована так, чтобы устра­нить как можно больше потенциальных зависимостей. С этой целью исполь­зовались простые форматы, простые способы адресации памяти и раздель­ные наборы аппаратных регистров для различных функций. Все вычисления производились с применением трехрегистрового формата, когда регистра­ми являлись 60-разрядные центральные регистры. Точно так же вся адреса­ция осуществлялась через отдельные адресные и индексные регистры. Это разделение и специализация функций позволили сделать более независимы­ми многие шаги выполнения команды, осуществить большее разбиение на ступени и тем самым большее перекрытие. Кроме того, в машинах семей­ства 6000 имелась центральная справочная таблица, содержавшая информа­цию о состоянии каждого ресурса в машине, который может быть исполь­зован той или иной командой, находящейся в данный момент на некоторой ступени обработки. Когда команда достигает ступени, на которой продол­жение ее выполнения зависит от некоторого ресурса, который в свою оче­редь может оказаться используемым некоторой другой командой, прово­дится сверка со справочной таблицей. Если дальнейшее выполнение команды не разрешалось, то оно временно откладывалось. В машинах семейства 6000 при этом останавливалось также исполнение последующих команд. Когда требования зависимости команд удовлетворялись (например, когда другая команда завершалась), по справочной таблице устанавливалось, что выпол­нение отложенной команды может теперь продолжаться, и осуществля­лось возвращение ее в активное состояние. Поскольку возможных зависи­мостей много (использование регистров, запоминание, за которым сле­дует загрузка с того же адреса, условные переходы и т.п.), исполнение отдельных команд могло задерживаться по нескольку раз.

Еще одна существенная особенность машин семейства 6000 — наличие у них многих независимых функциональных устройств (умножителей, сум­маторов и т. п.) для ступеней выполнения операций над данными. Когда очередная команда достигала данной ступени, операнды направлялись для обработки к свободному функциональному устройству соответствующего типа. Функциональное устройство помечалось как занятое до завершения операции и выдачи результата. Это также приводило к перекрытию многих различных команд.

Хотя машины семейства 6000 не были в строгом смысле конвейерными, благодаря своим особенностям они проложили путь будущим конвейерным машинам. Это хороший пример того, когда различия между чистой конвей­еризацией, перекрытием и чистым параллелизмом становились совсем рас­плывчатыми, но основные понятия функционального разбиения, обнару­жения и устранения помех четко рассматривались на стадии проектирования. В более поздних машинах, таких как машины семейства 7600, применяе­мые способы были улучшены путем большей конвейеризации, особенно в функциональных устройствах.

В машине IBM 360/91 был применен несколько иной подход1. Цель со­стояла в использовании конвейеризации для как можно большего увели­чения скорости исполнения более традиционного набора команд (архитек­тура системы 360). Поскольку архитектура набора команд не разрабатыва­лась специально для конвейерной реализации, было больше причин для возникновения межкомандных зависимостей. Поэтому большое внимание было уделено механизмам блокировок и разбиению системы, позволяв­шим осуществить как можно больше перекрытий. Это приводило, напри­мер, к частичной выборке обоих возможных наборов команд, следующих за командой условного перехода, когда результаты проверки условия за­висели от еще не завершенных команд. Когда результат становился извест­ным, ненужная последовательность команд отбрасывалась.

Весь процесс исполнения команды был сильно конвейеризован с множеством путей и специальных функций, введенных для повышения производительности. Фактически машина IBM 360/91 была одной из первых, в которой применялась иерархий конвейеров, причем са­мый верхний уровень состоял из двух ступеней: 1-устройства для выборки и предварительной обработки команды и Е-устройства для ее исполнения. Оба эти устройства сами были конвейерными.

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

Следующая разработка в области конвейерных машин вызвана необхо­димостью иметь в некоторых приложениях скорости исполнения, значитель­но более высокие, чем те, которые могут быть достигнуты при традицион­ных архитектурах. Эти прикладные задачи часто характеризовались серия­ми шагов, в которых на каждом шаге одна и та же функция последователь­но применялась к различным данным. Наборы таких данных названы век-горами. Был разработан новый класс команд, названных векторными, ко­торые позволяли программисту задать в одной команде один из этих базо­вых векторных шагов. Наряду с устранением накладных расходов, связанных с командами управления циклом, этот тип команд позволил разработ­чику ЭВМ обеспечить настройку внутренних конвейеров на прогон с мак­симальной скоростью без опасения встретить непредвиденные зависимости или помехи. Такие машины стали называться векторными процессорами.

В первую очередь к ним относятся матричный процессор 2938 фирмы IBM, машина STAR-100 фирмы Control Data и машина ASC фирмы Texas Instruments. Матричный процессор 2938 был чисто векторным, оп­тимизированным на выполнение умножений и сложений, подключался к шине памяти более традиционной машины и получал от нее цепочки вектор­ных команд.

Машина STAR-1001 имела как традиционные скалярные команды, так и векторные. Как и у машин семейства 6000, в ней имелось несколько не­зависимых функциональных устройств, но в машине STAR эти устройства были конвейерными. Кроме того, были разработаны специальные способы адресации, связанные с так называемыми двоичными векторами, чтобы дать возможность программисту записывать в компактной форме векторы, содержащие много нулевых элементов. При разработке машины Т1 ASC было выбрано другое направление: в машину были включены век­торные команды, способные обрабатывать векторы вплоть до трехмер­ных. Структура машины отличалась еще и тем, что единый внутренний арифметический конвейер мог динамически перестраиваться на выполне­ние любой базовой операции (умножения, сложения и т.д.,) над данными с фиксированной или с плавающей запятой. Машина могла содержать от од­ного до четырех таких конвейеров.

В новых разработках конвейерных структур пошли по пути расширения перекрытия функций высокого уровня. Например, машина 3838 фирмы IBM является, как и предыдущая машина 2938, присоединяемым векторным процессором, но с большим запасом векторных команд и бо­лее высокого уровня. В машине имеется несколько независимых обрабаты­вающих блоков, каждый из которых выполняет свою часть общего процес­са векторной обработки, а некоторые из этих блоков сами конвейеризова­ны на нескольких уровнях. Такая структура позволяет также осуществ­лять конвейеризацию и перекрытие на нескольких уровнях одновременно, совмещая их с исполнением различных программ нескольких независимых пользователей.

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

В более новых работах концепция хаотичного исполнения команд при­вела к исследованию машин на основе потока данных, в которых не задает­ся порядок исполнения, определяемый порядком команд в памяти. Здесь остаются, однако, помехи, связанные с зависимостью данных; например, команда j может в явном виде требовать данные, вырабатываемые ко­мандой 2.