У вас вопросы?
У нас ответы:) SamZan.net

Архитектура ВС ~ это абстрактное представление или определение физической системы с точки зрения програм

Работа добавлена на сайт samzan.net: 2016-03-13

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 11.3.2025

АРХИТЕКТУРА, СТРУКТУРА ВЫЧИСЛИТЕЛЬНОЙ СИСТЕМЫ

Понятия "архитектура, структура" вычислительной системы

При описании вычислительных систем (ВС) принято различать их  архитектуру и структурную организацию. Хотя общепринятого  определения  этих понятий нет, целесообразно его иметь.

По определению Г. Маерса «Архитектура ВС – это абстрактное представление  или определение физической системы  с точки зрения программиста, разрабатывающего программы на машинно-ориентированном языке, или разработчика компилятора. Она определяет принципы организации ВС и функции процессора и не отражает такие проблемы, как управление и передача данных внутри процессора, конструктивные особенности логических микросхем и специфика их производства».

Таким образом, термин архитектура ВС относится к тем характеристикам  ВС, которые доступны извне, т.е. со стороны программы, или, с другой точки зрения, оказывают непосредственное влияние на логику выполнения программы.

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

В число характеристик архитектуры входят:

- набор машинных команд;

- форматы и представление  данных;

- методы адресации памяти;

- механизм обращения к средствам ввода-вывода   и ряд других.

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

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

История развития вычислительной техники и современная практика проектирования ВС свидетельствуют о том, что разделение между структурной организацией и архитектурой имеет отнюдь не академический интерес. Многие фирмы — производители компьютерного оборудования предлагают на рынках целые семейства компьютеров, все члены которого имеют единую архитектуру, но отличаются структурной организацией. В результате разные модели семейства имеют разную цену и производительность. Опыт разработки семейств ВС показал, что архитектура может быть довольно консервативной и сохраняться на протяжении длительного времени, в то время как структурная организация быстро изменяется вслед за изменениями в технологии производства отдельных компонентов системы. Прекрасным примером тому может служить история семейства IВМ System/370. Первые несколько моделей ВС с этой архитектурой появились в 1970 г. Пользователей с относительно скромными потребностями могла вполне удовлетворить довольно дешевая модель с невысоким быстродействием, а затем, когда "появлялся аппетит", они могли рассчитывать на обновление компьютерного парка и сохранение при этом всего наработанного ранее фонда программного обеспечения. В течение последующего десятилетия фирма IВМ выпустила еще несколько моделей ВС с той же архитектурой, в которых использовалась более совершенная и менее дорогая элементная база, новые типы периферийных устройств и другие усовершенствования. В результате, по сравнению с первыми моделями, значительно возросла производительность при одновременном снижении цены, и в то же время была сохранена преемственность. Следует отметить, что архитектура IВМ System/370 выжила и по сей день используется в производстве больших ВС фирмы IВМ.

В классе систем, которые получили название микрокомпьютеры, связь между архитектурой и структурной организацией очень тесная. Изменения в технологии производства интегральных микросхем влияют не только на структуру такой ВС, но понуждают разработчиков создавать более мощную в функциональном смысле архитектуру. В общем случае для машин этого класса не так сильны требования к преемственности программного обеспечения на уровне машинных команд ВС разных поколений. В результате появляется больше возможностей "игры на параметрах" при принятии решений, относящихся к увязке структурной организации и архитектуры. Характерным примером является появление на рынке ВС с сокращенным набором команд — RISC (RISC — сокращение от reduce instruction set computer).

Общая структура и функции   вычислительной системы          

             

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

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

 Структура — это способ объединения компонентов подсистемы в единое целое, а функции  операции, выполняемые каждым компонентом в процессе реализации функции, назначенной всей подсистеме.

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

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

Функции ВС

Структура и функции ВС, если рассматривать их на самом верхнем уровне абстракции, по существу довольно просты. На рис. 1 представлены базовые функции, которые выполняет ВС.

ОПЕРАЦИОННАЯ СРЕДА (источники и приемники данных)

Рис. 1. Базовые функции ВС

В самом общем смысле таких функций всего четыре:

• обработка данных;

• хранение данных;

• перемещение данных;

• управление.

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

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

ВС должна также обладать способностью перемещать данные, причем в обе стороны, т.е. получать первичные данные из операционной среды и отправлять результаты обработки внешним абонентам. Среда, в которой "живет" ВС, состоит из устройств, играющих либо роль источников данных, либо роль приемников информации. Процесс перемещения данных между ВС и операционной средой принято называть процессом ввода-вывода, а устройства, входящие в состав операционной среды, — периферийными устройствами. Когда данные передаются на большое расстояние, т.е. выполняется обмен данными с удаленными устройствами, этот процесс принято называть передачей данных.

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

На этом, самом общем, уровне анализа множество операций, выполняемых в ВС, можно разделить на ограниченное число видов. На рис.1.2 схематически показаны четыре основных вида операций.

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

Второй вариант — ВС функционирует как устройство хранения данных (рис.1.2,6), обеспечивая циркуляцию информации в обе стороны между периферийными устройствами и средствами выполнения функции хранения (т.е. данные записываются в ВС или считываются из ВС).

Последние два варианта включают обработку (преобразование) данных — преобразуемые данные либо извлекаются из хранилища, и туда же отправляются результаты (рис.2,в), либо данные поступают из операционный среды, а результаты отправляются в хранилище (рис. 2, г).

Рис. 2. Основные типы операций в ВС:

а — перемещения данных от одного абонента к другому;

б — хранение данных;

в, г — преобразование данных

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

Возможности подстройки конфигурации ВС под перечень выполняемых функций очень ограничены. Основная тому причина — ВС по самой своей природе ориентирована на выполнение самых разнообразных задач, а потому практически вся ее специализация проявляется на стадии программирования, а не на стадии проектирования.

Структура ВС

На рис. 3 в самом общем виде представлена ВС в ее отношениях с внешним миром. ВС является объектом, способным некоторым образом взаимодействовать с внешней по отношению к ней средой через связи, которые можно разделить на две группы — связи с локальным периферийным оборудованием и связи для передачи данных на большое расстояние. В дальнейшем внимание, в основном, будет сосредоточено на внутренней структуре ВС.

Рис. 1.3. ВС как элемент информационной среды

На верхнем уровне иерархии эта структура выглядит так, как показано на рис. 1.3. На ней можно увидеть четыре основных компонента ВС.

Центральный процессор (ЦП) управляет функционированием всей системы и выполняет функции обработки информации. (Очень часто в наименовании этого компонента прилагательное "центральный" опускается).

Оперативная память хранит исходные данные и всю информацию, необходимую для их обработки.

Устройства ввода-вывода перемещают данные между ВС и окружающей средой в обе стороны.

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

В состав конкретной ВС могут входить один или несколько компонентов каждого типа. Как правило, в ВС имеется один ЦП, но в последние годы прослеживается тенденция включать в состав единой ВС несколько процессоров.

Сейчас для нас основной интерес представляет самый сложный компонент ВС — центральный процессор. Его структура  представлена на рис. 4.

Рис. 4.  Верхний уровень структурной организации ВС

В состав ЦП входят:

устройство управления, на которое возлагаются функции управления прочими компонентами ЦП и, следовательно, всей ВС;

арифметическое и логическое устройство (АЛУ), которое выполняет все операции, связанные с содержательной обработкой информации;

регистры, которые хранят оперативную информацию во время выполнения процессором текущей операции;

внутренние связи ЦП некоторый механизм, обеспечивающий совместную работу трех прочих компонентов ЦП.

Рис.5. Структура центрального процессора

Существует несколько подходов к структурной организации устройства управления, из которых наибольшее распространение получил принцип микропрограммной реализации управления. При использовании этого подхода структура устройства управления показана на рис. 1.6.

Рис. 6. Структура устройства управления

Контрольные вопросы

  1.  Что понимается под определением «архитектура вычислительной системы»?
  2.  Что такое структура вычислительной системы?
  3.  Почему архитектура вычислительной системы должна быть стабильной?
  4.  В чем причина изменчивости структуры вычислительной системы?
  5.  Какие основные функции вычислительной системы?
  6.  Назовите основные подсистемы вычислительной системы?

Основные подсистемы процессора и его структура при последовательном выполнении этапов команды

Принцип программного управления

Современные компьютеры строятся на принципе программного управления, который был  предложен в 1945 г. Джоном фон Нейманом  и с тех пор используется в качестве основного принципа построения компьютеров.

Принцип программного управления Дж.фон Неймана  состоит в следующем.

1. Информация кодируется в двоичной форме и разделяется  на элементы информации, называемые словами.        

2. Разнотипные слова информации различаются по способу использования, но не по способу кодирования.

3. Слова информации размещаются в ячейках памяти процессора и идентифицируются  номерами ячеек, называемых адресами слов.   

4. Алгоритм представляется в форме последовательности управляющих слов, называемых командами, которые  определяют наименование операции и слова информации, участвующие в операции. Алгоритм, представленный в терминах машинных команд, называется программой.

5. Выполнение вычислений, предписанных алгоритмом, сводится к последовательному выполнению команд в порядке, однозначно определяемых  программой.  

Использование в компьютерах (вычислительных системах) двоичных кодов продиктовано спецификой электронных схем. Совокупности битов информации, используемых для представления отдельных чисел, команд и пр., рассматриваются как самостоятельные информационные объекты и называются словами. Слово обрабатывается в вычислительной системе как одно целое - как машинный элемент информации.   

Второй пункт утверждает, что нет необходимости в различных способах кодирования разнотипных слов информации. Благодаря этому команды программы могут обрабатываться таким же образом,  как и данные, что приводит к интересным возможностям.

Третий пункт фиксирует специфику организации машинной памяти. Машинная память - это совокупность ячеек, каждая из которых  служит для хранения слова информации. Чтобы записать слово в память, необходимо  указать адрес ячейки, отведенной для хранения  данного слова. Чтобы выбрать слово из памяти (прочитать его), опять необходимо указать адрес ячейки, в которой хранится данное слово. Таким образом, адрес ячейки, в которой хранится величина или команда, становится идентификатором (именем) данной величины или команды.

На рис. 1 представлена упрощенная структурная схема компьютера  с коммуникационной подситсемой в виде общей шины.

Общая шина состоит из трех шин: шины управления; шины адреса и двунаправленной шины данных. В состав общей шины входит также арбитр.

Рис. 1. Упрощенная структурная схема компьютера  с коммуникационной подситсемой в виде общей шины.

Последовательность действий процессора при выполнении команд

При обработке машинной команды процессор выполняет следующие операции:

Извлечение команды процессор считывает команду из памяти.

Интерпретация команды, процессор расшифровывает команду и определяет, какие операции ему предстоит выполнить.

Извлечение данных для выполнения команды может потребоваться прочесть данные из памяти или из модуля ввода-вывода.

Обработка данных выполнение команды может потребовать преобразования данных, т.е. выполнения над ними определенных арифметических или логических операций.

Запись данных — если в процессе выполнения команды данные были изменены,  результат необходимо где-то зафиксировать. В частности, результат может быть записан в память или передан в модуль ввода-вывода.

  

Основной цикл обработки команды

Цикл обработки команды включает три основных фазы (шага, этапа):

фаза извлечения. Считывание очередной команды из памяти в процессор.

фаза выполнения. Расшифровка кода операции и выполнение соответствующих действий.

фаза прерывания. Если прерывания разрешены и имеется запрос прерывания, сохранение текущего состояния процесса и обслуживание прерывания.

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

На следующем шаге, называемом "декодирование" команда расшифровывается (декодируется).

Дальнейшие действия процессора в фазе выполнения зависят от  типа команды, кода операции, типа адресов операндов и результата.

В простейшем случае, когда операнды и результат операции заданы в регистрах, в фазе выполнение выполняется операция над операндами и результат заносится в указанный регистр.

В случае, когда  один из операндов (или результат операции) задан в оперативной памяти, то выполняется фаза «чтение операнда из оперативной памяти». Для этого в соответствии с заданным способом адресации формируется адрес операнда, который посылается в оперативную память. В ответ из оперативной памяти через некоторое время процессор получает операнд. После этого выполняется заданная операция над операндами, и результат заносится по заданному адресу.

Как, правило, во время фазы выполнения содержимое счетчика команд увеличивается на величину, равную числу байтов выполняемой команды, т.е. готовится адрес следующей команды.

В конце фазы выполнение проверяется наличие запросов на прерывание от внешних источников. При наличии запроса на прерывание от внешнего источника и при разрешении выполняется фаза прерывания. Анализируется тип запроса на прерывание, определяется адрес программы обработки этого прерывания, и управление передается этой программе.

Основные подсистемы процессора

На рис. 2 представлена структурная схема процессора с последовательным выполнением всех этапов команд.

Рис. 2. Структурная схема процессора с последовательным выполнением всех этапов команд.

В состав процессора входят:

устройство управления, на которое возлагаются функции управления прочими компонентами процессора  и, следовательно, всем компьютером;

арифметическое и логическое устройство (АЛУ), которое выполняет все операции, связанные с содержательной обработкой информации;

регистры, которые хранят оперативную информацию во время выполнения процессором текущей операции;

внутренние связи некоторый механизм, обеспечивающий совместную работу трех прочих компонентов процессора.

Организация  регистров

Память в компьютерной системе имеет иерархическую структуру. Чем более высокое положение в иерархии занимает определенный блок памяти, тем выше его быстродействие, меньше объем и выше стоимость хранения в пересчете на 1 бит. Набор регистров процессора представляет память самого верхнего уровня, находящегося в иерархии над уровнями оперативной памяти и кэш-памяти. Регистры процессора разделяются по функциям.

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

Регистры управления и состояния - используются для управления функционированием процессора. К этим регистрам иногда могут иметь доступ специальные привилегированные команды, которые используются только в программах операционной системы.

Вспомогательные регистры - для временного хранения информации при выполнении команд.

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

Регистры управления и состояния

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

Рассмотрим  основные типы регистров, встречающихся в разных моделях.

В процессе обработки машинной команды существенную роль играют четыре регистра управления:

Счетчик команд (РС)  - содержит адрес извлекаемой машинной команды;

Регистр текущей команды - содержит последнюю извлеченную машинную команду;

Регистр адреса в памяти - содержит адрес ячейки памяти;

Регистры данных памяти - содержит слово данных, которое должно быть записано в память или слово, только что извлеченное из памяти.

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

Четыре перечисленных регистра используются при перемещении данных между процессором и памятью. Но внутри процессора данные должны передаваться в АЛУ для обработки. АЛУ имеет доступ как к регистру данных, так и к программно доступным регистрам. Но возможен и такой вариант структуры процессора, в котором существуют дополнительные буферные регистры на стыке АЛУ с другими компонентами. Эти буферные регистры играют роль входных и выходных для АЛУ и обмениваются данными с регистром данных и с программно доступными регистрами.                                  

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

Контрольные вопросы

  1.  В чем состоит суть принципа программного управления?
  2.  Что такое алгоритм?
  3.  Что такое программа?
  4.  Назовите основные подсистемы процессора
  5.  Какие действия выполняет процессор при выполнении очередной команды?
  6.  Назовите основные фазы цикла обработки команды

Методы  повышения производительности (быстродействия) процессоров

Единицы измерения производительности процессора

На уровне интуиции с понятием производительности процессора проблем не возникает. Чем быстрее процессор выполняет программу, тем он более производителен. В качестве примера можно рассмотреть процесс конвертирования аудиофайла в формат MP3. Из двух процессоров более производительным  считается тот, который быстрее выполняет конвертирование. Другой пример — финальный рендеринг сцены, созданной в какой-либо программе по трехмерному моделированию (например, 3ds max или Maya). Чем быстрее процессор справится с задачей рендеринга, тем он более производителен. Таких примеров можно привести достаточно много, но и без того понятно, что производительность процессора связана со скоростью выполнения им команд программм. Собственно, именно таким образом и трактуется производительность процессора (Performance), под которой понимают скорость выполнение им команд (интструкций) программы (Instruction Per Second, IPS) или количество команд, выполняемых в единицу времени (за одну секунду). Если попытаться записать данное определение в виде математической формулы, то получится следующее:

Как известно, процессор работает на определенной тактовой частоте, которая является одной из его важнейших технических характеристик. За каждый такт, то есть промежуток времени, обратный тактовой частоте, процессор выполняет определенное количество команд. Поэтому вместо количества команд программы, выполняемых за единицу времени, удобнее рассматривать количество команд программы, выполняемых за один такт процессора (Instruction Per Clock, IPC). IPC зависит и от структуры процессора, и от технологии производства, определяющей минимальные размеры используемых транзисторов и их быстродействие, и от оптимизации программы к архитектуре процессора.

Методы увеличения производительности процессора

Увеличение частоты. На самом нижнем уровне - это и использование  наиболее быстродействующих элементов и плат с высокой плотностью монтажа, и передовая технология конструирования

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

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

2. Более быстродействующие элементы обычно имеют меньшую плотность монтажа, что, в свою очередь, требуют более длинных соединительных связей между платами и, следовательно, приводит к увеличению задержек (за счет соединений) и уменьшению выигрыша в производительности.

3. Более быстродействующие элементы обычно рассеивают больше тепла. Поэтому требуются специальные меры по отводу тепла, что еще больше снижает плотность монтажа и, следовательно, быстродействие. Для того чтобы избежать дополнительных расходов, задержек за счет соединений и увеличения рассеяния тепла, целесообразно, по-видимому, применять быстродействующие элементы не везде, а только в тех частях, которые соответствуют «узким местам». Однако, путь увеличения быстродействия элементов имеет свои ограничения и может наступить момент, когда станет необходимым или более целесообразным использовать для реализации операции сложения другие способы.

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

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

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

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

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

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

Использование конвейерного принципа и других структурных методов позволило существенно повысить производительность процессоров. Однако возможности традиционных структурных методов ускорения выполнения команд в одном процессоре (ядре) на современном этапе практически исчерпаны.

Следовательно, единственное направление, ведущее к дальнейшему повышению производительности - это  более полное использование параллелизма при обработке данных.

Об  увеличении тактовой частоты процессора

Переписав выражение для производительности компьютера в виде произведения количества команд, выполняемых за один такт процессора, на количество тактов процессора за единицу времени (тактовая частота процессора, F), получим:

Как видно, производительность компьютера прямо пропорциональна как тактовой частоте, так и количеству команд, выполняемых за один такт. Из этой формулы также следует, что существует два принципиально разных подхода к увеличению производительности компьютера. Первый из них заключается в увеличении тактовой частоты, а второй — в увеличении IPC.

На практике, как правило, реализуются оба подхода одновременно, то есть производительность компьютера увеличивается за счет как увеличения тактовой частоты, так и увеличения IPC. Вопрос лишь в том, какой из двух подходов является доминирующим.  IPC и максимально возможная тактовая частота компьютера взаимосвязаны.

До недавнего времени доминирующим средством увеличения производительности компьютера являлось увеличение тактовой частоты. Производительность компьютеров буквально отождествлялась с их тактовой частотой, а структура создавалась именно с расчетом обеспечения ее максимально возможного увеличения. Примером этого может служить структура NetBurst, положенная в основу процессоров семейства Pentium 4, особенностью которой являлся супердлинный конвейер, что позволяло наращивать тактовую частоту.

Негативные последствия увеличения тактовой частоты процессора

За пять лет выпуска процессоров семейства Pentium 4 их тактовая частота была увеличена более чем в три раза. Стартовав с отметки чуть больше 1 ГГц, за пять лет она достигла 3,8 ГГц.

Казалось бы, если увеличение  тактовой частоты представляет собой довольно эффективное средство для увеличения производительности процессоров. Что мешает и дальше двигаться в этом же направлении? Почему можно утверждать, что наращивание тактовой частоты процессоров как доминирующий способ увеличения производительности — это тупик?

Дело в том, что увеличение тактовой частоты процессора приводит к росту его энергопотребления и, как следствие, к повышению тепловыделения.

Зависимость потребляемой процессором мощности от его тактовой частоты можно представить следующей формулой:

 

Power = CU2F.

 

То есть, мощность, потребляемая процессором, прямо пропорциональна тактовой частоте (F), квадрату напряжения питания процессора (U2) и его так называемой динамической емкости (C). Учитывая, что сама тактовая частота обусловлена напряжением питания процессора, потребляемая мощность нелинейным образом зависит от частоты процессора. Соответственно получаем нелинейную связь между производительностью процессора и потребляемой им мощностью.

Эмпирическим путем установлено, что при увеличении  тактовой частоты на 20% производительность процессора возрастает примерно на 13%. Дело в том, что, несмотря на теоретическую прямолинейную зависимость между производительностью процессора и его тактовой частотой, в реальности она не является строго пропорциональной. При этом потребляемая процессором мощность возрастает на 73%! При уменьшении тактовой частоты процессора на 20% производительность уменьшается на 13%, а потребляемая мощность — на 49%! Этот пример наглядно демонстрирует, что увеличение тактовой частоты приводит к явному дисбалансу между приростом производительности и потребляемой мощностью.

В погоне за производительностью, которая, как уже отмечалось, в процессорах семейства Pentium 4 обеспечивалась главным образом увеличением тактовой частоты, последние версии процессоров на структуре NetBurst достигли уровня энергопотребления в 130 Вт. Казалось бы, ничего страшного — ведь это соответствует одной-двум лампам накаливания и любая люстра в квартире потребляет больше электроэнергии. Однако проблема заключается в том, что эта мощность выделяется процессором в виде тепла, что приводит к его нагреванию. И если для лампы накаливания такой нагрев не критичен, то для процессора все не так просто. Процессоры настольных ПК могут сохранять нормальную работоспособность вплоть до температуры 70 °С, а это означает, что при столь высоком энергопотреблении необходимо обеспечить эффективный отвод тепла, для чего используются процессорные вентилятоы (кулеры). Проблема, однако, заключается в том, что современные воздушные процессорные кулеры обеспечивают эффективное охлаждение процессоров при энергопотреблении только до 100 Вт — лишь немногие мощные устройства позволяют охлаждать процессоры с более высоким энергопотреблением, причем эти кулеры довольно шумные.

С учетом того, что энергопотребление десктопных процессоров семейства  Pentium 4 уже достигло своего критического значения, дальнейший рост их производительности стал невозможен в рамках существующей структуры. Можно говорить, что структура  NetBurst полностью исчерпала свои потенциальные возможности и создала своего рода тупиковую ситуацию в дальнейшем развитии процессоров.

Интересно отметить, что нелинейная зависимость между потребляемой мощностью и производительностью процессора была впервые подмечена Фредом Поллаком (Fred Pollack) в 1999 году, еще до внедрения структуры NetBurst. Остается лишь понять — если все с самого начала было известно, то зачем вообще понадобилось разрабатывать структуру NetBurst, у которой не было будущего? Скорее всего, ответ на этот вопрос достаточно прост:  в 2000 г.  когда проблема энергопотребления процессоров не стояла столь остро, проще было убедить всех в том, что будущее за тактовой частотой, а не заниматься разработкой новой структуры. Так , в 2000 г. фирма Intel обещала достичьв своих процессорах к 2010 г. рубежа в 10 ГГц. Мечты остались мечтами, а то, что должно было случиться, случилось. Сейчас о тактовой частоте процессоров как о средстве увеличения производительности уже не говорят.

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

Энергетическая эффективность процессора

Если абсолютную производительность процессора принято измерять в количестве программных команд, выполняемых в единицу времени (Instruction Per Second, IPS), то энергетическую эффективность процессоров можно характеризовать величиной, численно равной среднему количеству поглощенной энергии, приходящейся на одну выполненную команду (инструкцию Energy Per Instruction, EPI). EPI измеряется в джоулях (Дж) и определяется по следующей формуле:

 

EPI нетрудно связать и с другой часто используемой характеристикой энергетической эффективности процессора, иногда называемой оптимизированной производительностью процессора и определяемой как производительность процессора в расчете на каждый ватт потребляемой мощности (Performance Per Watt):

 

Соответственно:

 

EPI = Power / Performance.

Таким образом, энергетическую эффективность процессора EPI можно трактовать как потребляемую мощность в расчете на единицу производительности, если последняя измеряется в количестве команд, исполняемых за единицу времени.

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

Энергетическая эффективность процессоров зависит от таких факторов, как конструкция  процессора, технологический процесс производства и напряжение питания.

Возвращаясь к семейству процессоров  Pentium 4, отметим, что их структура  была изначально ориентирована на достижение максимальной производительности любыми путями. Речь идет о высокой динамической емкости процессоров, за счет чего они потребляют достаточно много энергии для обработки каждой команды (инструкции). Длинный конвейер, сложная структура блока внеочередного исполнения команд, спекулятивный характер обработки команд и многое другое — все это в конечном счете ведет к повышению значении EPI. Итак, к особенностям структуры  NetBurst можно отнести не только возможность увеличения производительности за счет увеличения  тактовой частоты, но и высокое значение EPI.

Пользователю хотелось бы иметь процессор, который, с одной стороны, был бы высокопроизводительным, а с другой — обладал бы низким значением EPI, то есть был бы энергоэффективным. Одновременно удовлетворить эти требования могут и процессоры на основе принципиально новой структуры, которая позволяла бы реализовать рост производительности за счет не увеличения  тактовой частоты, а увеличения количества команд, выполняемых процессором за один такт (IPC).

КОНВЕЙЕРНАЯ ОРГАНИЗАЦИЯ ОБРАБОТКИ КОМАНД

  

Разработчики структуры компьютеров издавна прибегали к методам проектирования, известным под общим названием "совмещение операций", при котором аппаратура компьютера в любой момент времени выполняет одновременно более одной базовой операции. Этот общий метод включает два понятия: параллелизм и конвейеризацию. Хотя у них много общего и их зачастую трудно различать на практике, эти термины отражают два совершенно различных подхода. При параллелизме совмещение операций достигается путем воспроизведения в нескольких копиях аппаратной структуры. Высокая производительность достигается за счет одновременной работы всех элементов структур, осуществляющих решение различных частей задачи.

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

Простейшая организация конвейера

Для иллюстрации основных принципов построения процессоров будет использоваться простейшая структура, содержащая 32 целочисленных регистра общего назначения (R0,...,R31), 32 регистра плавающей точки (F0,...,F31) и счетчик команд PC. Будем считать, что набор команд  процессора включает типичные арифметические и логические операции, операции с плавающей точкой, операции пересылки данных, операции управления потоком команд и системные операции. В арифметических командах используется трехадресный формат, типичный для RISC-процессоров, а для обращения к памяти используются операции загрузки и записи содержимого регистров в память.

Рассмотрим принципы конвейерной обработки информации на примере пятиступенчатого конвейера, в котором выполнение команды состоит из следующих этапов:

  1.  IF (INsTRuction Fetch) - считывание команды в процессор;
  2.  ID (INsTRuction DecodINg) - декодирование команды;
  3.  OR (Operand ReadINg) - считывание операндов;
  4.  EX (ExecutINg) - выполнение команды;
  5.  WB (Write Back) - запись результата.

Выполнение команд в таком конвейере представлено в табл. 1.

      Таблица 1. Порядок выполнения команд в 5-ступенчатом конвейре

Команда

Такт

1

2

3

4

5

6

7

8

9

i

IF

ID

OR

EX

WB

i+1

IF

ID

OR

EX

WB

i+2

IF

ID

OR

EX

WB

i+3

IF

ID

OR

EX

WB

i+4

IF

ID

OR

EX

WB

Оценка производительности  не идеального конвейера

Идеальным является  конвейер, в котором:

все этапы (ступени) имеют одинаковое время срабатывания;

отсутствуют конфликты;

все команды выполняются друг за другом в установившемся режиме, то есть без перезагрузки конвейера.

Наличие конфликтов в конвейере и его перезагрузки снижают реальную производительность конвейера по сравнению с идеальным случаем.

Пусть для выполнения отдельных стадий обработки требуются следующие затраты времени (в некоторых условных единицах):

tIF = 4, tID = 2, tOR = 1, tEX = 3, tWB = 4.

Поскольку в каждом такте могут выполняться различные стадии обработки команд, длительность такта конвейера выбирается исходя из максимального времени выполнения всех стадий и дополнительного времени  (tдоп), необходимого для  записи промежуточных результатов обработки в буферные регистры.

Тогда, предполагая, что дополнительные расходы времени составляют tдоп = 1 , получим время такта:

tконв = max {tIF=4, tID=2, tOR=1, tEX=3, tWB=4}+ tдоп=4+1=5.

Оценим время выполнения одной команды и  группы из N команд при последовательной и конвейерной обработке.

При последовательной обработке время выполнения N команд составит:

Tпосл = N*(tIF + tID + tOR + tEX + tWB)= 14N.

Анализ табл. 1 показывает, что при конвейерной обработке после того, как получен результат выполнения первой команды, результат очередной команды появляется в следующем такте работы процессора. Следовательно:

Tконв = 14  + (N-1)*tконв

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

Сокращение длительности такта может достигаться разбиением выполнения команды на большое число этапов, каждый из которых включает в себя относительно простые операции и поэтому будет выполняться за более короткий промежуток времени. Так, если в процессоре Pentium длина конвейера составляла 5 ступеней (при максимальной тактовой частоте 200 МГц), то в процессорах Pentium 4 на ядре Northwood длина конвейера составляла 20 ступеней, а в процессоре с ядром   Prescott она увеличена до 31 ступени при максимальной тактовой частоте 3,8 ГГц.

Конфликты в конвейере и способы минимизации их влияния на производительность процессора

Конфликты - это такие ситуации в конвейерной обработке, которые препятствуют выполнению очередной команды в предназначенном для нее такте.

Конфликты делятся на три группы:

структурные,

по управлению,

по данным.

Структурные конфликты

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

Причины структурных конфликтов:

  1.  Не полностью конвейерная структура процессора, при которой некоторые ступени отдельных команд выполняются более одного такта.

Пусть этап выполнения команды i+1 занимает 3 такта. Тогда диаграмма работы конвейера будет иметь вид, представленный в табл. 3.

Таблица 3. Конвейерная обработка при задержке команды i+1 на этапе EX

Команда

Такт

1

2

3

4

5

6

7

8

9

i

IF

ID

OR

EX

WB

i+1

IF

ID

OR

EX

EX

EX

WB

i+2

IF

ID

OR

O

O

EX

WB

i+3

IF

ID

OR

O

O

EX

i+4

IF

ID

OR

O

O

В этом случае в работе конвейера возникают так называемые "пузыри"  в обработке команд i+2 и следующих за ней начиная с такта 6, которые снижают производительность процессора.

Если какой-то блок конвейера вносит задержку, то тормозится работа всего конвейера. Образуемый при этом "пузырь" должен пройти от места своего возникновения до самого конца конвейера (если, например, возникла задержка на ступени считывания команды, то в следующем такте блок декодирования от него ничего не получит, а через 3 такта соответственно блок сохранения результатов ничего не получит от блока выполнения). Таким образом, скорость конвейера определяется скоростью самой медленной его ступени.

Этой ситуации можно было бы избежать двумя способами.

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

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

Недостаточное дублирование некоторых ресурсов

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

Борьба с конфликтами такого рода проводится путем увеличения количества однотипных функциональных устройств, которые могут одновременно выполнять одни и те же или схожие функции. В запоминающих устройствах в современных процессорах с этой целью разделяют кэш-память для хранения команд и кэш-память данных, а также используют многопортовую схему доступа к регистровой памяти, при которой к регистрам можно одновременно обращаться по нескольким каналам для записи и считывания информации. Например, в процессоре Itanium к блоку регистров общего назначения допускается одновременное обращение на выполнение 8 операций чтения и 6 операций записи. Конфликты из-за исполнительных устройств обычно сглаживаются введением в состав процессора дополнительных блоков. Например,  в процессоре Pentium 4 для обработки целочисленных данных было предусмотрено 4 АЛУ. При этом появляется возможность параллельной обработки информации в нескольких конвейерах. Процессоры, имеющие в своем составе более одного конвейера подготовки команд, называются суперскалярными.

Недостатком суперскалярных процессоров является необходимость синхронного продвижения команд в каждом из конвейеров.

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

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

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

Конфликты по управлению 

Конфликты по управлению возникают при конвейеризации команд переходов и других команд, изменяющих значение счетчика команд.

Суть конфликтов этой группы наиболее удобно проиллюстрировать на примере команд условного перехода. Пусть в программе, представленной в табл. 1, команда i+1 является командой условного перехода, формирующей адрес следующей команды в зависимости от результата выполнения команды i. Команда i завершит свое выполнение в такте 5. В то же время команда условного перехода уже в такте 3 должна прочитать необходимые ей признаки, чтобы правильно сформировать адрес следующей команды. Если конвейер имеет большую глубину (например, 20 ступеней), то промежуток времени между формированием признака результата и тактом, где он анализируется, может быть еще больше.

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

Можно несколько улучшить эту ситуацию, использую схему "задержанных переходов". При этом на стадии компиляции компилятор таким образом структурирует получаемый объектный код, чтобы сделать команды, следующие за командой перехода, действительными и полезными (рис. 1).

Рис.1.  Организация задержанного перехода

Слот задержки заполняется независимой командой, находящейся перед командой условного перехода. Эта команда выполняется за то время, пока процессор формирует истинное условие, по которому должно быть определено направление выполнения программы. Одной из основных трудностей в этом подходе является определение точного времени выполнения команды, вносимой в слот задержки. Аппаратура должна гарантировать реальное выполнение этих команд перед выполнением собственно перехода.

Более эффективными для снижения потерь от конфликтов по управлению являются методы предсказания переходов. Они призваны максимально ускорить определение адреса команды, выполняемой после команды перехода.

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

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

Методы предсказания переходов делятся на статические и динамические. При использовании статических методов до выполнения программы для каждой команды условного перехода указывается направление наиболее вероятного ветвления. Это указание делается программой-компилятором по заложенным в ней алгоритмам.  Также это может делать и сам программист по опыту выполнения аналогичных программ либо по результатам тестового выполнения программы. Например, в системе команд процессора Itanium для этого предназначена специальная команда.

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

Процессор начинает выбирать из памяти и выполнять команды по предсказанной ветви программы (так называемое исполнение по предположению, или "спекулятивное" исполнение). Однако так как направление перехода может быть предсказано неверно, получаемые результаты с целью обеспечения возможности их аннулирования не записываются в память или регистры (то есть для них не выполняется этап WB), а накапливаются в специальном буфере результатов.

Если после формирования анализируемых признаков оказалось, что направление перехода выбрано верно, все полученные результаты переписываются из буфера по месту назначения и выполнение программы продолжается в обычном порядке. Если направление перехода предсказано неверно, все команды, выбранные после перехода, помечаются, согласно интеловской терминологии, как поддельные.

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

Следует отметить, что конфликты по управлению не исчерпываются только проблемами, связанными с командами условных переходов. Они возникают при выполнении всех команд, меняющих значение счетчика команд. Это хорошо видно из табл. 1. Если команда i является командой такого типа (например, команда безусловного перехода), то адрес перехода будет вычислен ею в такте 5, в то время как уже в такте 2 необходимо выбирать в процессор следующую команду по этому адресу.

Методы динамического предсказания реализуются при выполнении программы в процессоре. Они осуществляют предсказание направления переходов на основании результатов предыдущих выполнений данной команды.

При использовании этих методов для команд условных переходов анализируется предыстория переходов - результаты нескольких предыдущих команд ветвления по данному адресу. В этом случае возможно определение чаще всего реализуемого направления ветвления, а также выявление чередующихся переходов.

Для команд безусловных переходов однажды вычисленный целевой адрес сохраняется в специальной памяти BTB (Branch Target Buffer), откуда он извлекается сразу же при декодировании данной команды.

Аналогичный подход используется для команд вызова - возврата из процедуры (анализ связок CALL - RETURN).

Конфликты по данным

Конфликты по данным возникают в случаях, когда выполнение одной команды зависит от результата выполнения предыдущей команды.

При обсуждении этих конфликтов будем предполагать, что команда i предшествует команде j.

Существует несколько типов конфликтов по данным:

  1.  Конфликты типа RAW (Read After Write - чтение после записи):

команда с номером jпытается прочитать операнд прежде, чем команда с номером  i запишет на это место свой результат. При этом команда с номером j может получить некорректное старое значение операнда.

Проиллюстрируем этот тип конфликта на примере выполнения команд, представленных на рис. 2.

Рис. 2.  Конфликт по данным типа RAW

Пусть выполняемые команды имеют следующий вид:

  1.   ADD R1,R0;        (R1=R1+R0)

i+1=j) SUB R2,R1;     (R2=R2-R1)

Команда с номером i изменит состояние регистра R1в такте 5. Но команда с номером  i+1 должна прочитать значение операнда R1 в такте 4. Если не приняты специальные меры, то из регистра R1будет прочитано значение, которое было в нем до выполнения команды с номером  i.

Конфликты типа RAW обусловлены именно конвейерной организацией обработки команд. Они называются истинными взаимозависимостями.

Уменьшение влияния конфликта типа RAW обеспечивается методом, который называется пересылкой или продвижением данных, обходом, иногда закороткой.

В этом случае результаты, полученные на выходах исполнительных устройств, помимо входов приемника результата передаются также на входы всех исполнительных устройств процессора (рис. 3).


Рис. 3.  Уменьшение влияния конфликта типа RAW методом продвижения данных

Если устройство управления обнаруживает, что полученный какой-либо командой результат требуется одной из последующих команд в качестве операнда, то он сразу же, параллельно с записью в приемник результата, передается на вход исполнительного устройства для использования следующей командой.

Главной причиной двух других типов конфликтов по данным является возможность неупорядоченного выполнения команд в современных процессорах, то есть выполнения команд не в том порядке, в котором они записаны в программе (ложные взаимозависимости).

  1.  Конфликты типа WAR (Write After Read - запись после чтения)

Команда с номером  j пытается записать результат в приемник, прежде чем он считается оттуда командой с номером  i. При этом команда с номером  i может получить некорректное новое значение операнда:

i) ADD R1,R0              (R1=R1+R0);

i+1 = j) SUB R0,R2        (R0=R0-R2).

Этот конфликт возникнет в случае, если команда с номером  j вследствие неупорядоченного выполнения завершится раньше, чем команда с номером  i прочитает старое содержимое регистра R0.

  1.  Конфликты типа WAW (Write After Write - запись после записи):

команда с номером  j пытается записать результат в приемник, прежде чем в этот же приемник будет записан результат выполнения команды с номером  i, то есть запись заканчивается в неверном порядке, оставляя в приемнике результата значение, записанное командой с номером  i:

i) ADD R1,R0                (R1=R1+R0);

. . .

j) SUB R1,R2                 ( R1=R1-R2).

Устранение конфликтов по данным типов WAR и WAW достигается путем отказа от неупорядоченного исполнения команд, но чаще всего путем введения буфера восстановления последовательности команд.

Часть конфликтов по данным может быть снята специальной методикой планирования компилятора. В простейшем случае компилятор просто планирует распределение команд в базовом блоке.

Базовый блок представляет собой линейный участок последовательности программного кода с одним входом и одним выходом, в котором отсутствуют внутренние команды перехода. Поскольку в таком блоке каждая команда будет выполняться, если выполняется первая из них, - можно построить граф зависимостей этих команд и упорядочить их так, чтобы минимизировать приостановки конвейера. Эта техника называется планированием загрузки конвейера или планированием потока команд.

Например, для оператора А = B + С компилятор, скорее всего, сгенерирует следующую последовательность команд:

  1.  Rb = B.
  2.  >Rc = C.
  3.  Ra = Rb + Rc.
  4.  A = Ra.

Очевидно, выполнение команды (3) должно быть приостановлено до тех пор, пока не станет доступным поступающий из памяти операнд C.

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

Пусть, например, имеется последовательность операторов:

А = B + С;

D = E - F.

В этом случае компилятор может сгенерировать следующую последовательность команд, выполнение которой не приведет к приостановке конвейера:

  1.  Rb = B.
  2.  Rc = C.
  3.  Re = E.
  4.  Ra = Rb + Rc.
  5.  Rf = F.
  6.  A = Ra.
  7.  Rd = Re - Rf.
  8.  D = Rd.

Заметим, что использование разных регистров для первого и второго компилируемого оператора было достаточно важным для реализации такого правильного планирования. В частности, если переменная e была бы загружена в тот же самый регистр, что b или c, такое планирование не было бы корректным. В общем случае планирование конвейера может потребовать увеличенного количества регистров.

Для простых конвейеров стратегия планирования на основе базовых блоков вполне удовлетворительна, однако когда конвейеризация становится более интенсивной и действительные задержки конвейера растут, требуются более сложные алгоритмы планирования.

Зачастую зависимость по данным не является необходимой - просто так уж повелось у программистов: чем меньше переменных (и регистров в программах на ассемблере) использует программа - тем лучше. В результате зачастую получается, что вся программа использует один-два регистра с зависимостью по данным чуть ли не в каждой паре команд.

Метод переименования регистров

Устранение конфликтов, связанных с ложными взаимозависимостями данных, часто возможно путем переименования регистров (register renaming). Суть этого механизма заключается в следующем. Процессоры, использующие переименование регистров,  имеют значительно больше физических регистров по сравнению с архитектурными регистрами. При этом если какой-либо команде требуется использовать регистр, процессор динамически ставит в соответствие этому логическому (архитектурному) регистру один из более многочисленных физических регистров. Если другая команда пытается обратиться к тому же логическому регистру, процессор для предотвращения конфликта может поставить ему в соответствие другой физический регистр. Такие переименования действуют, пока команды продвигаются по конвейерам.

Таким образом, каждый раз, когда команда прямо или косвенно пишет в регистр, ей выделяется новый физический регистр. В процессоре  имеется таблица отображения логических (видимых программисту) архитектурных регистров на физические (видимые только процессору). Когда команде выделяется новый физический регистр, таблица обновляется: логический (архитектурный) регистр, на который ссылалась команда, ставится в соответствие выделенному физическому регистру (табл.5).

Таблица 5. Механизм переименования регистров

Команда

Действие

Рабочий регистр

i

Пишет в R0

С этого момента регистру R0 соответствует выделенный для команды регистр PHY0

i+1

Читает из R0

Читает из PHY0

i+2

Пишет в R0

С этого момента регистру R0 соответствует выделенный для команды регистр PHY1

i+3

Читает из R0

Читает из PHY1

При определении операндов команды имена логических (архитектурных) регистров преобразуются в имена физических, после чего значения последних заносятся в поля операндов микрокоманд. Микрокоманды работают только с физическими регистрами.

Как можно увидеть, после декодирования команды с номером i, которая в качестве приемника результата использует логический регистр R0, все прочие команды, использующие в качестве операнда R0, будут обращаться к физическому регистру, выделенному для команды с номером  i. При этом если какая-то команда после команды с номером i будет писать в тот же логический регистр, ей будет выделен новый физический регистр, и все команды после нее будут использовать уже новый регистр.

Из табл. 5 видно, что команды стали независимы. Если команды, работающие с логическим регистром R0, зависят друг от друга и их нельзя выполнять параллельно, то микрокоманды "разведены" по физическим регистрам PHY0 и PHY1 и независимы.

Значение физического регистра переписывается в архитектурный, когда завершается выполнение команды (фиксируется ее результат). В свою очередь, завершение выполнения команды происходит, когда все предыдущие команды успешно завершились в заданном программой порядке.

Однако такой подход требует, чтобы процессор помимо программно доступных архитектурных регистров содержал блок из гораздо большего количества невидимых программисту физических регистров, что и реализовано в большинстве современных процессоров. Например, в процессоре Itanium файл физических регистров имеет емкость 128 строк.

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

Контрольные вопросы

В чем  состоит суть конвейерной обработки команд?

Охарактеризуйте работу простейшего конвейера команд

Какова идеальная производительность конвейера команд?

Что мешает идеальной работе конвейера команд?

В чем суть конфликта по данным?

В чем суть конфликта по управлению?

Что такое структурный конфликт?

Как разрешаются структурные конфликты?

Методы повышения производительности  конвейера команд в современных процессорах

Сокращение потерь на выполнение команд перехода и минимизация конфликтов по управлению

Конфликты по управлению могут вызывать даже большие потери производительности конвейера, чем конфликты по данным. Когда выполняется команда условного перехода, она может либо изменить, либо не изменить значение счетчика команд. Если команда условного перехода заменяет счетчик команд значением адреса, вычисленного в команде, то переход называется выполняемым; в противном случае, он называется невыполняемым.

Простейший метод работы с условными переходами заключается в приостановке конвейера как только обнаружена команда условного перехода до тех пор, пока она не достигнет ступени конвейера, которая вычисляет новое значение счетчика команд (табл.1). Такие приостановки конвейера из-за конфликтов по управлению должны реализовываться иначе, чем приостановки из-за конфликтов по данным, поскольку выборка команды, следующей за командой условного перехода, должна быть выполнена как можно быстрее, как только будет известно окончательное направление команды условного перехода.

Таблица 1. Приостановка конвейера при выполнении команды условного перехода

Команды перехода

IF

ID

Следующая команда

 

IF

Следующая команда +1

 

 

Следующая команда +2

 

 

Следующая команда +3

 

 

Следующая команда +4

 

 

Следующая команда +5

 

 

Например, если конвейер будет приостановлен на три такта на каждой команде условного перехода, то это может существенно отразиться на производительности процессора. При частоте команд условного перехода в программах, равной 30% и идеальном CPI, равным 1, машина с приостановками условных переходов достигает примерно только половины ускорения, получаемого за счет конвейерной организации. Таким образом, снижение потерь от условных переходов становится критическим вопросом. Число тактов, теряемых при приостановках из-за условных переходов, может быть уменьшено двумя способами:

          Обнаружением является ли условный переход выполняемым или невыполняемым на более ранних ступенях конвейера.

           Более ранним вычислением значения счетчика команд для выполняемого перехода (т.е. вычислением целевого адреса перехода).

Реализация этих условий требует модернизации исходной схемы конвейера.

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

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

Снижение потерь на выполнение команд условного перехода

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

Метод выжидания

 Простейшая схема обработки команд условного перехода заключается в «замораживании» или «подавлении» операций в конвейере, путем блокировки выполнения любой команды, следующей за командой условного перехода, до тех пор, пока не станет известным направление перехода. Рис. 1 отражал именно такой подход.

Привлекательность такого решения заключается в его простоте.

Метод возврата

Более хорошая и не намного более сложная схема состоит в том, чтобы прогнозировать условный переход как невыполняемый. При этом аппаратура должна просто продолжать выполнение программы, как если бы условный переход вовсе не выполнялся. В этом случае необходимо позаботиться о том, чтобы не изменить состояние процессора до тех пор, пока направление перехода не станет окончательно известным. В некоторых процессорах эта схема с невыполняемыми по прогнозу условными переходами реализована путем продолжения выборки команд, как если бы условный переход был обычной командой. Поведение конвейера выглядит так, как будто ничего необычного не происходит. Однако, если условный переход на самом деле выполняется, то необходимо просто очистить конвейер от команд, выбранных вслед за командой условного перехода и заново повторить выборку команд (табл 2).

Таблица 2. Диаграмма работы модернизированного конвейера

Невыполняемый условный переход

IF

ID

Команда i+1

 

IF

Команда i+2

 

 

Команда i+3

 

 

Команда i+4

 

 

Выполняемый условный переход

IF

ID

Команда i+1

 

IF

Команда i+2

 

 

Команда i+3

 

 

Команда i+4

 

 

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

Задержанные переходы

 Четвертая схема, которая используется в некоторых процессорах, называется "задержанным переходом". В задержанном переходе такт выполнения с задержкой перехода длиною n есть.

Команды с номерами i - n находятся в слотах (временных интервалах) задержанного перехода. Задача программного обеспечения заключается в том, чтобы сделать команды, следующие за командой перехода, действительными и полезными. Аппаратура гарантирует реальное выполнение этих команд перед выполнением собственно перехода. Здесь используются несколько приемов оптимизации.

На рис.3. а показаны три случая, при которых может планироваться задержанный переход.

Рис. 3. Пример планирования  задержанного перехода

В верхней части рисунка для каждого случая показана исходная последовательность команд, а в нижней части - последовательность команд, полученная в результате планирования. В случае (а) слот задержки заполняется независимой командой, находящейся перед командой условного перехода. Это наилучший выбор. Стратегии (b) и (c) используются, если применение стратегии (a) невозможно.

В последовательностях команд для случаев (b) и (c) использование содержимого регистра R1 в качестве условия перехода препятствует перемещению команды ADD (которая записывает результат в регистр R1) за команду перехода. В случае (b) слот задержки заполняется командой, находящейся по целевому адресу команды перехода. Обычно такую команду приходится копировать, поскольку к ней возможны обращения и из других частей программы. Стратегии (b) отдается предпочтение, когда с высокой вероятностью переход является выполняемым, например, если это переход на начало цикла.

Наконец, слот задержки может заполняться командой, находящейся между командой невыполняемого перехода и командой, находящейся по целевому адресу, как в случае (c). Чтобы подобная оптимизация была законной, необходимо, чтобы можно было все-таки выполнить команду SUB, если переход пойдет не по прогнозируемому направлению. При этом мы предполагаем, что команда SUB выполнит ненужную работу, но вся программа при этом будет выполняться корректно. Это, например, может быть в случае, если регистр R4 используется только для временного хранения промежуточных результатов вычислений, когда переход выполняется не по прогнозируемому направлению.

Рис. 4 показывает различные ограничения для всех этих схем планирования условных переходов, а также ситуации, в которых они дают выигрыш.

Рассматриваемый
случай

Требования

(a)

Команда условного перехода не должна зависеть от переставляемой команды

(b)

Выполнение переставляемой команды должно быть корректным, даже если переход не выполняется.
Может потребоваться копирование команды

(c)

Выполнение переставляемой команды должно быть корректным, даже если переход выполняется

Рис. 4.

Компилятор должен соблюдать требования при подборе подходящей команды для заполнения слота задержки. Если такой команды не находится, слот задержки должен заполняться пустой операцией.

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

Ряд исследований  эффективности планирования переходов для простейшего конвейера с одним слотом задержки перехода при использовании простого алгоритма планирования  показывает, что больше половины слотов задержки переходов оказываются заполненными. При этом почти 80% заполненных слотов оказываются полезными для выполнения программы. Это может показаться удивительным, поскольку условные переходы являются выполняемыми примерно в 53% случаев. Высокий процент использования заполненных слотов объясняется тем, что примерно половина из них заполняется командами, предшествовавшими команде условного перехода (стратегия (a), выполнение которых необходимо независимо от того, выполняется ли переход, или нет.

Имеются небольшие дополнительные затраты аппаратуры на реализацию задержанных переходов. Из-за задержанного эффекта условных переходов, для корректного восстановления состояния в случае появления прерывания нужны несколько счетчиков команд (один плюс длина задержки).

Статическое прогнозирование условных переходов: использование технологии компиляторов

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

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

Проблемы реализации точного прерывания в конвейере

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

Как и в не конвейерных машинах двумя основными проблемами при реализации прерываний являются:

  1.   прерывания возникают в процессе выполнения некоторой команды;

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

В последовательность команд, поступающих на обработку в конвейер, принудительно вставить команду перехода на прерывание.

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

После передачи управления подпрограмме обработки прерываний операционной системы, она немедленно должна сохранить значение адреса команды (PC), вызвавшей прерывание. Это значение будет использоваться позже для организации возврата из прерывания.

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

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

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

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

Ступень конвейера

Причина прерывания

IF

Ошибка при обращении к странице памяти при выборке команды;

не выровненное обращение к памяти; нарушение защиты памяти

ID

Неопределенный или запрещенный код операции

EX

Арифметическое прерывание

MEM

Ошибка при обращении к странице памяти при выборке данных;

не выровненное обращение к памяти; нарушение защиты памяти

WB

Отсутствует

Рис. 6. Причины прерываний в простейшем конвейере

 

Суперскалярность и внеочередное исполнение команд

Основная черта всех современных процессоров состоит в том, что они способны запускать на исполнение не только ту команду, которую (согласно коду программы) следует исполнить в данный момент времени, но и другие «вблизи» неё. Приведём простой (канонический) пример. Пусть нам следует исполнить следующую последовательность команд:

  1.  A = B + C
  2.  Z = X + Y
  3.  K = A + Z

Легко заметить, что команды (1) и (2) совершенно независимы друг от друга — они не пересекаются ни по исходным данным (переменные B и C в первом случае, X и Y во втором), ни по месту размещения результата (переменная A в первом случае и Z во втором). Стало быть, если на данный момент у нас есть свободные исполняющие блоки в количестве более одного, данные команды можно распределить по ним, и выполнить одновременно, а не последовательно*. Таким образом, если принять время исполнения каждой команды равным N тактов процессора, то в классическом случае исполнение всей последовательности заняло бы N*3 тактов, а в случае с параллельным исполнением — всего N*2 тактов (так как команду (3) нельзя выполнить, не дождавшись результата исполнения двух предыдущих).

Разумеется, степень параллелизма не бесконечна: команды могут быть выполнены параллельно только в том случае, когда на данный момент времени есть в наличии соответствующее количество свободных от работы блоков (ФУ), причём именно таких, которые «понимают» рассматриваемые команды. Например, ALU физически неспособно исполнить инструкцию для FPU. Обратное также верно.

На самом деле, всё ещё сложнее. Так, если имеется следующая последовательность:

  1.  A = B + C
  2.  K = A + M
  3.  Z = X + Y

То очередь исполнения команд процессором будет изменена! Т.к. команды (1) и (3) независимы друг от друга ни по исходным данным, ни по месту размещения результата, они могут быть выполнены параллельно — и будут выполнены параллельно. А вот команда (2) будет выполнена после них (хронологически третьей) — поскольку для того, чтобы результат вычислений был корректен, необходимо, чтобы перед этим была выполнена команда (1). Механизм «внеочередное исполнение команд» (Out-of-Order Execution или «OoO обеспечивает выдачу команд на высполнение не в указанной в программе последовательности, а в той, которая позволяет достичь максимального быстродействия.

Теперь  должно стать окончательно понятно, зачем современным CPU такое количество однотипных исполняющих блоков: они обеспечивают возможность параллельного выполнения нескольких одинаковых или близких по типу команд, которые в случае с «классическим» подходом к проектированию процессора пришлось бы выполнять так, как они содержатся в исходном коде, одну за другой.

На рис. 7 приведена исполнительная часть ядра процессора Deneb в качестве наглядной иллюстрации возможностей параллельного выполнения команд



Рис.  7. «Исполнительная» часть ядра процессора Deneb в качестве наглядной
иллюстрации возможностей параллельного выполнения команд

Процессоры, оснащённые механизмом параллельного исполнения нескольких подряд идущих команд, принято называть «суперскалярными». Однако не все суперскалярные процессоры поддерживают внеочередное исполнение. Так, в первом примере  достаточно «простой суперскалярности» (выполнения двух последовательных команд одновременно) — а вот во втором примере без перестановки команд местами уже не обойтись, если необходимо получить максимальное быстродействие. Все современные процессоры с архитектурой x86  обладают обоими качествами: являются суперскалярными и поддерживают внеочередное исполнение команд — кроме ряда  версий процессора  Atom, который сделан с простой внутренней структурой, чтобы быть дешёвым и энергоэффективным одновременно. В то же время, были в истории процессоров с архитектурой  x86 и «простые суперскаляры», OoO не поддерживающие. Например, классическим десктопным x86-суперскаляром без OoO был процессор  Pentium (с или без MMX). Тот же процессор Atom можно с натяжкой считать аналогом процессора Pentium, хотя сильно продвинутым и по структуре, и по скорости.

Контрольные вопросы

  1.  В чем  состоит суть конвейерной обработки команд?
  2.  Что мешает идеальной работе конвейера команд?
  3.  В чем суть конфликта по данным?
  4.  В чем суть конфликта по управлению?
  5.  В чем суть переименования регистров?
  6.  Почему необходмо внеочередное выполнение команд?
  7.  Какова эффективность предсказания переходов?
  8.  Что такое суперскалярность?

Основные особенности организации  обработки команд в реальных  процессорах

Основные особенности структуры ядер современных  процессоров следующие:

Большая длина конвейера. 

Суперскалярная организация. Это   означает, что на каждом этапе обрабатываются сразу несколько потоков команд (операций)  параллельно — от выборки из кэша команд до полного завершения («отставки»). Суперскалярность наряду с тактовой частотой является важнейшим показателем пропускной способности процессора. Уровень суперскалярности («ширина обработки», гарантированно обеспеченная на всех этапах) в современных производительных процессорах варьируется от 3 до 4-5.

Предварительное преобразование процессорных  команд в промежуточные операции (микрооперации), более удобные для обработки и исполнения. Иногда такие операции называют RISC-подобными, исходя из того, что архитектуры RISC (дословно «компьютеры с сокращённым набором команд») разрабатывались как раз для того, чтобы обеспечить простоту, удобство и эффективность обработки машинных команд. Преобразование команд является необходимым для архитектуры IA-32 с её крайне нерегулярной и запутанной системой команд. Однако и для достаточно регулярной RISC-архитектуры  такое преобразование также производится — оно необходимо для разбиения некоторых сложных команд на простые операции. Для унификации в дальнейшем во всех случаях эти микрооперации  называют «МОПами» (либо просто «операциями»).

Внеочередное исполнение операций. Это  означает, что операции не обязаны выполняться в функциональных устройствах строго в том порядке, который определён в программном коде. Более поздние (по коду) операции могут исполняться перед более ранними, если не зависят от порождаемых ими результатов. Процессор должен лишь гарантировать, чтобы результаты «внеочередного» выполнения программы совпадали с результатами «правильного» последовательного выполнения. Механизм внеочередного исполнения позволяет в значительной степени сгладить эффект от ожидания считывания данных из кэшей верхних уровней и из оперативной памяти, что может занимать десятки и сотни тактов. Также он позволяет оптимизировать выполнение смежных операций, особенно при наличии сложных зависимостей между ними в условиях высокой латентности исполнения в устройствах и недостаточного количества регистров.

Поскольку исходная программа подразумевает последовательную модель исполнения, машинные команды должны считываться также последовательно. Кроме того, есть такое понятие, как «отставка» команды, которое подразумевает, что данная команда выполнена вместе со всеми командами, которые ей предшествовали в тексте программы. Таким образом, команды уходят в «отставку» строго последовательно, именно в том порядке, который задаётся программой.

Понятия «отставки» является ключевым в отображении внеочередного исполнения команд внутри процессора в чисто последовательное исполнение в «модели процессора», как она представляется пользователю. Может оказаться, что какая-то операция уже выполнилась в своём функциональном устройстве — но при этом не должна была выполняться, так как было неправильно предсказано направление условного перехода либо были считаны данные с неправильного адреса. Такое выполнение называется «спекулятивным» или «выполнением по предположению». Когда будет правильно исполнена предшествующая ей команда  перехода или чтения данных, такая неверная «спекулятивная» ветвь будет отменена, и при необходимости команда будет выполнена вновь (либо выполнится другая ветвь). Процедура «отставки» команды гарантирует, что она была выполнена «правильно». Любые прерывания процессора (по вводу-выводу либо аварийному событию) могут происходить только в момент «отставки»  команды, к которой это прерывание относится.

Предсказание ветвлений и выполнение команд по предположению «спекулятивное» выполнение.

Иерархическая структура подсистемы кэш-памяти.

Большое число специализированных функциональных исполнительных устройств.

Буферирование на всех этапах конвейера и др.

Пример структуры  ядра процессора приведен на рис. 1.

Рисунок 1.   Структура K10 ядра процессора фирмы AMD

Основные этапы выполнения команд

Выборка команд

Исполнение кода процессором начинается с процесса выборки команд и данных из подсистемы кэш-памяти (прежде всего из кэша L1К). При неудачном обращении в подсистему кэш-памяти выполняется обращение в оперативную память. Команды x86 имеют переменную длину, что затрудняет определение их границ перед декодированием. Для того, чтобы определение длины команд не влияло на темп декодирования, выполняется предварительное декодирование команд во время загрузки строк в кэш команд L1К. Информация о разметке команд хранится в кэше L1К в специальных полях (3 бита информации предекодирования на каждый байт команды). Предекодирование при загрузке в кэш позволяет вынести накладные расходы на определение границ команд за пределы каналов декодирования и поддерживать постоянный темп декодирования вне зависимости от длины и структуры команд. Процессоры загружают команды из кэша блоками 16 – 32 байта, из которых выделяются команды, направляемые на декодирование.

Предсказание переходов и ветвлений

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

Декодирование

Полученные из кэша команд блоки копируются в буфер предекодирования, где происходит выделение команд из блоков, определение их типов и отсылка в соответствующие каналы декодера. Декодер преобразует  x86-команды в простейшие машинные команды (микрооперации) фиксированной длины, называемые микрооперациями (МОП). Команды x86 разделяются на простые (Small x86 Instruction) и сложные (Large x86 Instruction). Простые команды при декодировании представляются с помощью одной-двух микроопераций, а сложные команды — тремя и более микрооперациями.  Простые команды отсылаются в аппаратный декодер, построенный на логических схемах, а сложные — в микропрограммный декодер. Этот декодер представляет собой своеобразный программный процессор. Он содержит программный код, хранящийся в специальной памяти MIS (Microcode Instruction Sequencer), на основе которого воспроизводится последовательность микроопераций. Выходящие каждый такт из декодера МОПы, объединяются в группы по 3 или 4.

Блок управления командами

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

Выполнение микроопераций

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

В хронологическом порядке, каждый МОП может проходить через следующие стадии:

  1.  находится в очереди планировщика, но ещё не готов к исполнению;
  2.  готов к исполнению (все аргументы операции вычислены);
  3.  выполняется;
  4.  выполнен и ждёт «отставки» либо отмены «спекулятивной» ветви;
  5.  находится в процессе «отставки».

Длина буфера переупорядочения в современных процессорах составляет несколько десятков элементов (от 40  до 126 и более). В случае если в начале очереди «застрянет» МОП, находящийся в процессе исполнения (например, ожидающий конца медленной операции или прихода данных из памяти), и новые МОПы будут поступать в полном темпе, буфер декодированных МОПов заполнится за 20-40 тактов. На практике, средний темп выполнения операций находится на уровне 50% от предельного уровня или несколько ниже. Взяв такой же темп поступления МОПов, получим время заполнения на уровне 40-80 тактов. Это существенно меньше, чем время ожидания данных из оперативной памяти (120-200 тактов и более). Приведённые цифры показывают, что при большом числе обращений к данным, которых нет в кэшах, и для которых не осуществляется эффективная предвыборка, буфер МОПов будет, как правило, переполнен, и процессор будет простаивать в ожидании прихода данных из памяти. По существу, в каждый момент времени работу будет блокировать единственный МОП, находящийся в начале очереди и ожидающий загрузки данных. Размер буфера МОПов в данном случае определяет, сколько МОПов, расположенных после этого, может быть помещено в него и исполнено (при условии, что они не зависят от загружаемых данных) до тех пор, пока процессор не остановится.

Выводы

Структуры реальных современных процессоров очень сложные. Как правило, в современных универсальных процессорах для персональных компьютеров (такие процессоры имеют очень сложно устроенную структуру) реализованы самые разнообразные методы повышения производительности.

Это:

конвейерность с числом ступеней  не менее 10-12;

суперскалярность с уровнем 3-4. Под суперскалярностью понимается число команд которые дешифрируются  в одном такте.

большое число специализированных функциональных устройств обработки данных;

внеочередное выполнение команд;

предсказание ветвлений;

иерархические подсистемы памяти, включающие до трех уровней кэш-памяти;

сложные дешифраторы команд и т.п.

Модель конвейерного суперскалярного компьютера

Подсистема генерации команд

 Модель подсистемы генерации команд приведена на рис. 1.

У

Рис. 1. Модель   подсистемы генерации команд.

Основная функция подсистемы генерации команд – генерация заявок (команд) для подсистемы обработки.

РНК – регистр текущего номера команды

Содержит виртуальный адрес текущего блока командной информации.

Выдает виртуальный адрес текущего блока командной информации в преобразователь виртуальных адресов в физические.

Код операции – чтение блока командной информации.

Преобразователь виртуальных адресов в физические

(буфер TLB для кэшей L1K, L1D)

Это кэш-память чисто ассоциативного типа. На вход этого кэша подается виртуальный номер страницы (старшие разряды виртуального адреса). Выполняется  сравнение этого виртуального номера с содержимым  каждой ячейки кэша.

При удачном поиске из кэша извлекается  номер физической страницы. К нему присоединяется смещение  в странице (например, 12 младших разрядов виртуального адреса при 4 Кбайтной странице) и физический адрес готов.

Вероятность удачного поиска в TLB - РTLB.

В современных процессорах емкость буфера TLB составляет десятки строк или даже сотни  строк. Это означает, например, что будет быстрое преобразование виртуального адреса в физический адрес (ВА→ФА) для достаточно большого   адресного пространства.  

В случае неудачного поиска (вероятность этого (1- РTLB) в процессоре возникает прерывание. Обработка этого прерывания происходит в привеллигированном режиме при отключенном кэше L1K. Время обработки этого прерывания очень большое. В первом приближении можно пренебречь вариантом с неудачным поиском. Тогда будем иметь РTLB=1.

Время удачного поиска и формирования физического адреса несколько  тактов.

Кэш команд L1K 

Размеры кэша команд L1K в современных процессорах:

фирма Intel - со структурами  Core 2, Nehalem - 32 Кбайта;

фирма AMD – процессоры Phenom Х2, Х3, Х4, Opteron, Barcelona, Shanghai - 64 Кбайт.

Кэш L1K – частично ассоциативный. У процессоров фирмы Intel степень ассоциативности значительно больше чем у процессоров фирмы AMD.

Вероятность удачного обращения в кэш L1K зависит от многих факторов:

  •  емкости;
  •  степени ассоциативности;
  •  локальности программы.

Основным фактором, обуславливающим вероятность удачного обращения, является локальность выполняемых программ. Вероятность удачного обращения в кэш L1K  РL1K.   

При неудачном обращении в кэш L1К блокируется прием новых заявок на чтение блоков командной информации и выдается заявка на чтение блока командной информации  в кэш  L2.

Время обслуживания заявок в кэше  L1K  кτ.

Разблокировка приема новых заявок происходит только после получения запрашиваемого блока из кэша L2.

Дешифратор команд

На вход дешифратора команд из кэша L1K  поступает (через n тактов в зависимости от модели процессора и ситуации) блок командной информации, например блок из 16 или 32-х байтов. В последних моделях процессоров как фирмы  Intel (со структурами Core 2, Nehalem), так и фирмы AMD (со структурами Phenom, Opteron) из кэша L1K читается за одно обращение 32 байта. После предварительной дешифрации (на этом этапе устанавливаются границы отдельных команд) основной Дешифратор команд выбирает из соответствующего буфера  последовательные команды. дешифратор генерирует 4 команды за один такт.

Появление команд в группе случайное с вероятностью Рi.

 Перечень команд.

  1.  Условный переход по циклу (по счетчику цикла).
  2.  Условный переход по результату сравнения (сравниваются 2 целочисленные величины).
  3.  Условный переход по результату сравнения двух чисел с плавающей точкой.
  4.  Сложение/вычитание целых чисел.
  5.  Умножение целых чисел.
  6.  Деление целых чисел.
  7.  Прочие операции с целыми числами (сдвиг, логические операции).
  8.  Сложение/вычитание чисел с плавающей точкой.
  9.  Умножение чисел с плавающей точкой.
  10.  Деление чисел с плавающей точкой.
  11.  Засылка в регистр общего назначения (LDф).
  12.  Засылка в регистр числа с плавающей точкой (LDпт).
  13.  Запись из регистра общего назначения в ОП (STф).
  14.  Запись из регистра числа с плавающей точкой в ОП (STпт).
  15.  Вызов процедуры.
  16.  Возврат из процедуры

Каждой команде присваивается текущий номер (целое 32 разрядное  положительное число).

Общий буфер заявок (ОБЗ)

Предназначен для хранения продешифрированных команд. Размер – N команд. ОБЗ – это ассоциативный буфер. Каждая команда занимает одну строку.

Структура команды:

номер команды – 32 разрядное целое число;

код операции  (1 байт) – в зависимости  от типа команды;

признаки состояния команды (команда готова к выполнению, команда не готова к выполнению, так как зависит от результатов выполнения других команд, команда выполняется, строка свободна, команда выполнена, другие);

номера команд от результатов которых зависит команда (не более двух команд);

Планировщик выдачи заявок из ОБЗ

Планировщик выдачи команд из ОБЗ анализирует  состояние всех специализированных функциональных устройств (ФУi), а также наличие  заявок в ОБЗ.

Если в ОБЗ для ФУi есть хотя бы одна готовая к выполнению команда и ФУi свободно (освободилась первая ступень конвейера – если ФУi конвейерного типа, или завершено выполнение заявки – если ФУi комбинационного типа), то планировщик выдает команду из ОБЗ на вход ФУi . 

Заявки из ОБЗ  выдаются на выполнение не в том порядке, в каком они следуют в программе, а по готовности. К конкретному ФУi  готовые к выполнению  заявки выдаются в соответствии с дисциплиною FIFO.

При заполнении общего буфера заявок (ОБЗ)  дешифратору команд запрещается  записывать новые команды.

В одном такте планировщик может выдать в функциональные устройства ограниченное количество команд.

После выдачи команды на выполнение в ФУ планировщик  устанавливает признак «команда выполняется»  в строке, которую занимала команда. Эта строка остается занятой до тех пор, пока команда не покинет систему. Выполненная команда с номером i покидает систему только после того, как покинет систему команда с номером i-1.

Планировщик удаления команд из системы

Планировщик удаления команд из системы  анализирует  в порядке следования команд  в программе состояние признаков «выполнено» всех команд, имеющихся в буфере упорядочивания.

Если признак «выполнено» команды с номером i установлен и все предшествующие команды с номерами (i-j, j=1,2,3……) удалены из ОБЗ, то:

команда с номером i считается удаленной (результат этой команды записывается в указанный программистом архитектурный регистр (или регистры);

строка ОБЗ, которую занимала команда с номером i,  объявляется свободной. В следующем такте  в эту строку может быть записана новая команда из дешифратора команд.

Если признак «выполнено» команды с номером i не установлен, то дальнейший просмотр буфера упорядочивания прекращается.

Модель подсистемы выполнения команд

Вычислительные функциональные устройства

ФУ сложения/вычитания целых чисел

Это ФУ комбинированного типа. Время обслуживания один такт (1τ).

Заявки к ФУ сложение/вычитание из ОБЗ выдает планировщик.

ФУ умножитель целых чисел

Это ФУ конвейерного  типа. Заявки к ФУ умножения целых чисел  из ОБЗ выдает планировщик.

ФУ умножения целых чисел   всегда готово к приему очередной заявки.

ФУ Делитель целых чисел

Делитель целых чисел это – ФУ комбинационного типа.

Время выполнения заявки Kτ.

Универсальное ФУ

Универсальное функциональное устройство является устройством комбинационного типа.

Время обслуживания заявок это  случайная величина, распределенная по показательному закону со средним временем 4τ.

 

Функциональные устройства для работы с числами с плавающей точкой

Сложитель/Умножитель

Эти ФУ  являются  устройствами конвейерного типа.  Могут различаться количеством ступеней. Для сложителя  количество ступеней К1, для умножителя – К2.

Делитель чисел с плавающей точкой

Структура и функционирование аналогично делителю целых чисел. Устройство комбинационного типа.

Время обслуживание заявок l тактов.

ФУ обращения в память (ФУ LD/ST)

Состоит из трех устройств (ступеней):

формирователя виртуального адреса операнда;  

преобразователя виртуального адреса в физически адрес ( ВА->ФА);

кэша  L1D.

Очередная команда  обращения в память (Load или Store)  заносится в буфер формирователя виртуального адреса операнда   при условии, что там есть место.

Размер буфера – n  заявок.

Сформированный ВА поступает в блок преобразования ВА->ФА (блок TLB).

Физический адрес (ФА) из блока TLB  поступает в кэш первого уровня L1D. Каждый блок выдаёт заявку в следующий блок только при условии, что тот готов принять её. Иначе он  блокируется.

Если поиск в кэше L1D прошёл успешно, команда LD/ST считается выполненной (об этом делается отметка “выполнено» в соответствующей записи ОБЗ).

Кэш L1D становится готовым к выполнению новых заявок.

Если поиск в  кэше L1D прошёл неудачно (промах), то формируется заявка в кэш более высокого уровня L2; кэш L1D объявляется свободным и готовым к приёму новых заявок.

 

                             Ступени ФУ LD/ST  

Формирователь виртуального адреса операнда

Принимаем, что ВА формируется за 1τ (один такт). Если следующая ступень конвейера в ФУ LD/ST свободна, то ВА передаётся туда, т.е. в блок TLBD (в преобразователь ВА->ФА).

             

Преобразователь  ВА->ФА

Структурно это чисто ассоциативная кэш-память аналогичная кэшу TLBL1К. Принцип действия также аналогичный.

Время преобразования ВА->ФА – 2 такта.

Принимаем, что вероятность удачи при обращении в эту ступень РTLBL1D=1 и пренебрегаем неудачными обращениями, так как они очень редки.

                                              Кэш  L1D

Структурно, по ёмкости кэш L1D аналогичен кэшу L. Вероятность удачного обращения РL1D.  Вероятность удачи  РL1D < РL, так как свойство локальности для данных, как правило, выполняется хуже.

Время удачного обращения в кэш L1D  (1-2) τ. При неудачном поиске в кэше L1D с вероятностью (1- РL1D ) выдается заявка в кэш L2, общий как для чтения блоков командной информации,  так и для команд обращения в память, если в кэше L1D промах.

 

Кэш L2  

На входе кэша L2 имеется один регистр для приема заявки от кэша L1K, и буфер - для заявок из кэша L1D.

Если кэш L2 свободен, то выбирается очередная заявка (или от кэша L1K , или от кэша L1D).

При наличии заявок от кэша  L1K и кэша L1D    высший приоритет имеет заявка из кэша L1K.

С вероятностью PL или PL2D («удача»)  время обслуживания заявки

 tобсл L2 = (12-14) τ.

На это время блокируется выбор новых заявок с любого направления.

С вероятностью (1- PL) или (1- PL2D) в случае «неудачи»  формируется заявка на чтение  из кэша третьего уровня (если он имеется в процессоре) или из  оперативной памяти. На все время обслуживания заявок на чтение блока командной информации  блокируется направление от УУ, то есть невозможно поступление заявок на новые команды.

Заявка i  к последующему уровню подсистемы памяти (к кэшу L3 – если он есть в процессоре,  или к оперативной памяти) помещается в очередь ожидающих обслуживания из предыдущегоо  уровня подсистемы памяти. Кэш   L2  открывается для приема новых заявок как на чтение команд, так и на чтение данных.

При выдаче заявки в к последующему уровню подсистемы памяти (L3 – если он имеется – или ОП), кэш L2 должен подготовить место для приема блока из этого уровня. Возможны 2 варианта:

  1.  в кэше L2 – есть свободное место;
  2.  в кэше L2 – нет свободного места.

В варианте 1 – никаких дополнительных действий выполнять не надо.

В варианте 2  необходимо выбрать блок на удаление. Если удаляемый блок  не изменен, то никаких действий выполнять не надо

 tвыбора места = х τ.

Если же удаляемый блок изменен  - необходимо переслать его в последующий уровень подсистемы памяти.  Записи выполняются  в фоновом режиме.

Кэш L3  

На входе кэша L3 имеется буфер  для приема заявок от кэша L2.

С вероятностью PL3 («удача»)  время обслуживания заявки

 tобсл L2 = (30-50) τ.

С вероятностью (1- PL3) в случае «неудачи»  формируется заявка к оперативной памяти.

При выдаче заявки в оперативную  память  кэш L3 должен подготовить место для приема блока из оперативной памяти. Возможны 2 варианта:

  1.  в кэше L3 – есть свободное место;
  2.  в кэше L3 – нет свободного места.

В варианте 1 – никаких дополнительных действий выполнять не надо.

В варианте 2  необходимо выбрать блок на удаление. Если удаляемый блок  не изменен, то никаких действий выполнять не надо

 tвыбора места = х τ.

Если же удаляемый блок изменен  - необходимо записать  его в оперативную память. Для записи блоков в ОП имеется специальный буфер (размер буфера  - несколько блоков -  4-8). Записи в оперативную память выполняются  в фоновом режиме.

 

Оперативная память

На входе оперативной памяти  имеется буфер  для приема заявок от кэша последнего уровня.

Время обслуживания заявки на чтение блока данных (преимущественно размером 64 байта) в современных вычислительных системах составляет около 50 нс. В зависимости от частоты процессора

tобсл ОП = (150-200) τ.

Заявка на чтение блока данных считается выполненной после записи блока в кэш L3. Информация об этом сообщается в кэш L3.

Особенности структуры основных подсистем  процессоров

Особенности кэшей

Частота работы кэша и его шина

Во всех современных процессорах кэши L1 и L2 работают на той же частоте, что и процессорное ядро. Однако скорость работы с кэшем зависит не только от частоты, но и от ширины шины, с помощью которой он соединён с ядром. Скорость передачи данных является произведением частоты работы шины (количества тактов в секунду) на количество байт, которые передаются по шине за такт.  В случае с кэшем более популярен  вариант увеличения ширины шины. Более того, можно поставить сразу две параллельные шины, передающие данные в разные стороны — т.е., преобразовав шину в двунаправленную (полнодуплексную) удвоенной ширины.

Большинство современных моделей имеют встроенный многоканальный контроллер оперативной памяти, общая эффективная ширина которого — 128 и более бит. Внутри процессора ширина шин между ядром и кэшами, а также самими кэшами может быть ещё шире: например — 256 бит.

Эксклюзивный и не эксклюзивный кэш

Концепции эксклюзивного и не эксклюзивного кэширования очень просты: в случае не эксклюзивного кэша, информация на всех уровнях кэширования может дублироваться. Таким образом, L2 может содержать в себе данные, которые уже находятся в L1I и L1D, а L3 может содержать в себе полную копию всего содержимого L2 (и, соответственно, L1I и L1D). Эксклюзивный кэш, в отличие от не эксклюзивного, предусматривает чёткое разграничение: если информация содержится на каком-то уровне кэша — то на всех остальных она отсутствует. Плюс эксклюзивного кэша очевиден: общий размер кэшируемой информации равен суммарному объёму кэшей всех уровней — а у не эксклюзивного кэша размер кэшируемой информации (в худшем случае) равен объёму самого большого (по размеру и по номеру) уровня кэша. Минус эксклюзивного кэша менее очевиден, но он есть: необходим специальный механизм, который следит за собственно «эксклюзивностью» (например, «удаление» информации из L1 фактически инициирует процесс её копирования в L2).

Не эксклюзивный кэш традиционно использует компания Intel, эксклюзивный  — компания AMD. В целом, здесь  наблюдается классическое противостояние между объёмом и скоростью: за счёт эксклюзивности, при одинаковых объёмах L1/L2 у процессоров фирмы AMD общий размер кэшируемой информации получается больше — но за счёт неё же он работает медленней (задержки, вызванные наличием механизма обеспечения эксклюзивности). Следует заметить, что недостатки не эксклюзивного кэша фирма Intel компенсирует просто, но весомо: наращивая его объёмы.

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

Многоуровневое кэширование

Специфика конструирования современных процессорных ядер привела к тому, что систему кэширования в подавляющем большинстве процессоров  приходится делать многоуровневой. Кэш первого уровня (самый «близкий» к ядру) традиционно разделяется на две (как правило, равные) части: кэш инструкций (L1I) и кэш данных (L1D). Это разделение предусматривается так называемой «гарвардской архитектурой» процессора, которая по состоянию на сегодня является самой популярной для построения современных процессорах. В L1I, соответственно, аккумулируются только команды (с ним работает декодер), а в L1D — только данные (они впоследствии, как правило, попадают во внутренние регистры процессора). Иерархически «над» L1 стоит кэш второго уровня — L2. Он, как правило, в 2-8 раз больше по объёму, примерно втрое медленнее, и является уже «смешанным» — там располагаются и команды, и данные. В первых многоядерных процессорах у каждого ядра были свои L1, но общий L2. В настоящее время  у каждого ядра процессоров для высокопроизводительных компьютеров есть свой кэш L2, а общим для всех ядер является L3 (кэш третьего уровня), который значительно больший (более 1 Мбайт  для каждого ядра), и ещё примерно 3-4 раза  медленнее (но всё ещё значительно быстрее оперативной памяти).

Алгоритм работы с многоуровневым кэшем в общих чертах не отличается от алгоритма работы с одноуровневым, просто добавляются дополнительные итерации: сначала информация ищется в L1, если там промах — в L2, потом — в L3, и уже потом, если ни на одном уровне кэша она не найдена — идёт обращение к основной оперативной памяти.

На рис. 3  представлены примеры  структуры 2- и 4-х ядерных процессоров фирмы AMD.



Рис. 3. Структуры 2- и 4-х ядерных процессоров фирмы
AMD

В  структуре К10 процессоров  фирмы AMD использует общий для всех ядер кэш третьего уровня. В структуре фирмы  AMD К8, все ядра имели только свои собственные кэши 1 и 2 уровня.Примерно так же выглядят  структуры процессоров фирмы Intel.

Декодер

Исполнительные блоки всех современных  x86-процессоров не работают с командами архитектуры x86. У каждого процессора есть своя, «внутренняя» система команд, имеющая мало общего с теми командами, которые поступают извне. В общем случае, команды, исполняемые ядром — намного проще, «примитивнее», чем команды архитектуры  x86. Чтобы процессор с точки зрения программиста или пользователя «внешне выглядел» как x86 процессор, существует декодер: этот блок отвечает за преобразование «внешнего» x86-кода во «внутренние» команды, исполняемые ядром (при этом достаточно часто одна команда x86-кода преобразуется в несколько более простых «внутренних»). Декодер является важной частью современного процессора: от его быстродействия зависит то, насколько постоянным будет поток команд, поступающих на исполняющие блоки. Ведь они не способны работать с кодом x86, поэтому будут ли они что-то делать или простаивать — во многом зависит от эффективности работы декодера.

Регистры процессора

Регистры — по сути, те же ячейки памяти, но «территориально» они расположены прямо в процессорном ядре. Разумеется, скорость работы с регистрами намного больше не только скорости работы с ОЗУ, но и с кэшами любого уровня. Поэтому большинство команд архитектуры x86 предусматривают осуществление действий именно над содержимым регистров, а не над содержимым памяти. Однако общий объём регистров процессора, как правило, очень мал — он не сравним даже с объёмом кэшей первого уровня и составляет всего сотни байт. Поэтому код программы (не на языке высокого уровня, а именно машинный) обычно содержит примерно такую последовательность операций: загрузить в регистры процессора информацию из ОЗУ, произвести некое действие над содержимым этих регистров, поместив результат туда же, в регистры, а потом снова выгрузить результат в основную память. Т.к. работа с памятью куда медленнее, было бы неплохо, чтобы объём данных в регистрах был больше — тогда промежуточные результаты вычислений можно целиком (или почти…) хранить в ядре, не обращаясь даже в кэш, что резко ускорит работу процессора. Однако увеличить размер или число регистров значительно сложнее, чем увеличить кэш и, тем более, нарастить объём памяти (это вообще любой продвинутый пользователь сделает). Тем не менее, примерно раз в 5-10 лет к стандартному на этот момент набору регистров добавляется ещё столько же новых, либо сами регистры удваиваются (а при введении x86-64 с целочисленными регистрами произошло и то, и другое).

Функциональные устройства

Пройдя через все уровни кэша, декодер и некоторые подготовительные модули, команды наконец-то попадают в те блоки, ради которых вся эта катавасия и устраивалась: функциональные (исполняющие) устройства (ФУ). По сути, именно они и являются единственно необходимым элементом процессора. Можно обойтись без кэша — скорость снизится, но программы работать будут. Можно обойтись без декодера — исполняющие устройства станут сложнее, но работать процессор будет. Более того, у процессоров с системой команд концепции RISC (с точки зрения программиста, архитектура x86 к ней не отсносится, но для примера имеет смысл заметить) декодер отсутствует принципиально. А без функциональных устройств обойтись невозможно, ибо именно они исполняют операции над данными. Разных ФУ бывает много, но самые главные из них — арифметико-логические устройства (ALU), блоки вычислений с плавающей точкой (FPU), блоки векторной обработки (SIMD — таково общее название концепции векторных вычислений, означающее «одна команда, много данных») и блоки обмена данных с памятью.  Каждое ФУ может исполнить только те команды, которые предназначены для него. Распределением команд, поступающих с декодера, по различным исполняющим устройствам занимается специальный блок-планировщик.

Целочисленные арифметико-логические устройства

АЛУ (ALU) (целочисленный арифметический блок) традиционно отвечают за самые частые операции: простые арифметические действия (сложение, вычитание, сравнение) с целыми числами, логические операции («и», «или», «исключающее или» и «не»), копирование и простые преобразования чисел, а также битовые сдвиги. Блоков ALU в современных процессорах, как правило, несколько – 3 и более.

Здесь не указаны ещё некоторые команды с целыми числами, которые, вроде бы должны быть исполнены в АЛУ. Например — умножение. Однако всё не так просто. Дело в том, что число и разнообразие функциональных устройств зависит от частоты встречаемости разных команд. Т.к. команды сложения, вычитания и копирования среди целых чисел наиболее «популярны», имеет смысл делать несколько АЛУ, исполняющих именно их, а вот целочисленное умножение, и, тем более, деление встречается куда реже, поэтому целочисленный умножитель почти во всех ядрах процессоров один (иногда — универсальный, в т.ч. и для вещественных чисел), а делителя нет вообще (эта операция делается в умножителе с использованием специальных таблиц констант для ускорения деления).

Блоки вычислений с плавающей запятой и векторной обработки

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

Часто каждый блок умеет делать копирование данных, но только 2 или 3 исполняют простые команды (как у целочисленного АЛУ — их иногда называют SIMD ALU или SSE ALU), только один — умножение и деление, и ещё один — всё остальное (перетасовки элементов вектора, сложные преобразования форматов данных и пр.).

Блоки обмена данных с памятью

Тут есть 3 вида модулей — 2-3 так называемых AGU (АЛУ для формирования виртуальных адресов) или устройства генерации адреса, подготавливающие адрес операции обращения в память, и по одному блоку загрузки и сохранения (выгрузки), соединённых с кэшем данных первого уровня. Тут всё просто — готовится адрес, а затем либо пишутся данные из регистра в кэш, либо наоборот — читаются данные из кэша в регистр.

Энергосбережение

Помимо вычислительных «наворотов», у ядер современных процессоров есть ещё и различные технологии для уменьшения потребления энергии. Причём это касается процессоров не только для мобильных устройств, но и для настольных ПК, и даже серверов. Дело в том, что уменьшение потребления электроэнергии также приводит к уменьшению тепловыделения, которое за последние годы сильно выросло — ещё 10 лет назад было трудно себе представить, что средний процессор будет потреблять электричества и выделять тепла под 100 ватт, а то и больше. Системы охлаждения всё чаще становятся слишком дорогими и шумными, притом, что это один из самых ненадёжных узлов компьютера, требующий регулярного ухода. А если охлаждение не справится — процессор (или другой чувствительный компонент) перегреется.  Поэтому используютсяехнологии регулировки потребления энергии в зависимости от требуемой загрузки процессора.

Анализируя загрузку различных блоков и шин, контроллер энергосбережения может снизить их частоту работы (для компонентов, которые могут работать несинхронно) или приостановить тактирование полностью, а также указать материнской плате понизить питающее напряжение (тоже — не всего процессора, а отдельного ядра или блока, хотя и не каждого). Регулировка напряжений особенно эффективна, т.к. от него потребляемая и выделяемая мощность зависит больше. Однако и частота (за редкими исключениями) и напряжение не могут упасть до нуля: реально частота падает в 2-3 раза относительно максимума, а напряжение — процентов на 20-30. Т.е. даже при полном простое (чего в многозадачных ОС не бывает никогда) процессор всё равно будет потреблять несколько ватт, а особо энергоэффективные процессоры для ноутбуков — доли ватта. Тем не менее, это на порядок меньше, чем в случае отсутствия энергосберегающих технологий. Разумеется, во всех современных материнских платах и ОС энергосбережение процессора поддерживается и включено по умолчанию. Что касается эффективности, то считается, что технологии AMD чуть отстают от Intel, но реальная разница скорее всего окажется околонулевой, т.к. процессор — не единственная часть компьютера. В частности, современная видеокарта «налегает на ватты» посильнее многих серверных процессоров, даже если она в корпусе одна; аналогично и для ноутбуков.

Также заметим, что переход на новый технологический процесс при изготовлении микросхем (он измеряется в нанометрах и определяет минимальный размер элемента на чипе) помимо возможности размещения большего числа транзисторов и ускорения их срабатывания также приводит и к уменьшённому энергопотреблению. Так что, например, одинаковые по устройству и частоте процессоры, изготовленные, например, по 32-нанометровой и 22-нанометровой технологии, будут потреблять разное количество энергии — у второго будет чуть меньшее питающее напряжение и потребляемый ток.

Предварительное (опережающее) декодирование и кэширование

Предсказание ветвлений

В любой более-менее сложной программе присутствуют команды условного перехода: «Если некое условие истинно — перейти к исполнению одного участка кода, если нет — другого». С точки зрения скорости выполнения кода программы современным процессором с большим числом подоготовительных стадий и собственно исполнением (так называемый исполнительный конвейер), любая команда условного перехода — воистину бич божий. Ведь до тех пор, пока не станет известно, какой участок кода после условного перехода окажется «актуальным» — его невозможно начать декодировать и исполнять. Для того чтобы как-то примирить концепцию «длинных» конвейеров с командами условного перехода, предназначается специальный блок: блок предсказания ветвлений. Занимается он, по сути, «пророчествами»: пытается предсказать, на какой участок кода укажет команда условного перехода, ещё до того, как она будет исполнена, и сработает ли переход вообще. В соответствии с указаниями «штатного внутриядерного пророка», процессором производятся вполне реальные действия: «напророченный» участок кода загружается в кэш (если он там отсутствует), и начинается декодирование и выполнение его команд. Причём среди выполняемых команд также могут содержаться инструкции условного перехода, и их результаты тоже предсказываются, что порождает целую цепочку из пока не проверенных предсказаний! Разумеется, если блок предсказания ветвлений ошибся, вся проделанная в соответствии с его предсказаниями работа просто аннулируется.

Алгоритмы, по которым работает блок предсказания ветвлений, вовсе не являются шедеврами искусственного интеллекта. Когда процессор впервые встречает условный переход, он пытается предсказать его поведение «по одёжке» — какого типа команда, куда происходит переход (вперёд по ходу исполнения программы или назад — это если он вообще произойдёт) и пр.. Точность такого предсказателя (он называется статическим) невелика. Самое интересное происходит, когда встречается уже знакомый переход. Чтобы его узнать, у предсказателя есть специальная таблица историй переходов, хранящая описание поведения нескольких сотен или тысяч последних обнаруженных в программе команд ветвления вместе с их адресами. Далее уже динамический предсказатель делает заключение о вероятном поведении команды не «по одёжке», а «по уму» — основываясь на детальной накопленной статистике поведения и этой команды перехода, и предыдущих её «коллег», исполненных до неё. Для поддержки этой статистики каждый раз, когда команда перехода доходит до исполнения, её результат попадает в предсказатель, чтобы тот скорректировал свою таблицу — перешли или нет, угадали или нет.

Несмотря на достаточно высокую эффективность алгоритмов, механизмы предсказания ветвлений в современных CPU всё равно постоянно совершенствуются и усложняются — но тут уже речь идёт о борьбе за единицы процентов: например, за то, чтобы повысить эффективность работы блока предсказания ветвлений с 95 процентов до 97, или даже с 97 до 99…

Предвыборка данных

Блок предвыборки данных (Prefetch) очень похож по принципу своего действия на блок предсказания ветвлений — но в данном случае речь идёт не о коде, а о данных. Общий принцип действия такой же: предзагрузчик (префетчер) анализирует запросы к данным, решает, что к некоему участку памяти, ещё не загруженному в кэш или ядро, скоро будет осуществлён доступ — и заранее даёт команду на загрузку данного участка ещё до того, как он понадобится программе. «Умно» (результативно) работающий блок предвыборки позволяет существенно сократить время доступа к нужным данным, и, соответственно, повысить скорость исполнения программы. Он хорошо компенсирует высокую латентность подсистемы памяти, подгружая нужные данные поближе к ядру или сразу в него, и тем самым, нивелируя задержки при доступе к ним, если бы они находились не в кэше, а в основном ОЗУ.

Разумеется, в случае предвыборки неизбежны негативные последствия: загружая ненужные (как позже окажется) данные в кэш, Prefetch вытесняет из него другие (быть может, как раз нужные). Кроме того, за счёт «предвосхищения» операции считывания, создаётся дополнительная нагрузка на контроллер памяти (причём в случае ошибки — совершенно бесполезная).

Алгоритмы Prefetch, как и алгоритмы блока предсказания ветвлений, тоже не блещут интеллектуальностью: как правило, данный блок стремится отследить, не считывается ли информация из памяти с определённым «шагом» (по адресам), и на основании этого анализа пытается предсказать, с какого адреса будут считываться данные далее. Как и в случае с блоком предсказания ветвлений, простота алгоритма вовсе не означает низкую эффективность: в среднем, блок предвыборки чаще «попадает», чем ошибается — это, как и в предыдущем случае, прежде всего связано с тем, что «массированное» чтение данных из памяти, как правило, происходит при исполнении различных циклов.

Контрольные вопросы

  1.  Назовите основные стадии конвера команд современных универсальных процессоров.
  2.  Сколько уровней кэш-памяти в современных процессорах?
  3.  Функции кэш-памяти первого уровня?
  4.  Функции кэш-памяти второго уровня?
  5.  Функции кэш-памяти третьего уровня?
  6.  Почему кэш-память первого уровня разделяют на кэш-память команд и кэш-память данных?
  7.  Какой размер блока данных, передаваемых между уровнями кэш-памяти?
  8.  Какой размер блока передается из оперативной памяти в кэш-память последнего уровня?
  9.  Что такое предвыборка?
  10.  Какое различие между между организацией кэш-памяти в процессорах фирм Intel и AMD?
  11.  Какие функции декодера?
  12.  Зачем нужно переименование регистров?
  13.  Какие размеры буферов для хранения команд гоотовых к выдаче в исполнительные функциональные устройства?
  14.  Почему необходим буфер для хранения выполненых команд?
  15.  Функции предсказателя переходов?
  16.  Функции планировщика выдачи команд на выполнение?

Структуры современных процессоров фирмы Intel

О  технологических процессах изготовления процессоров

На рис. 1 приведены  перечень структур и технологических процессов изготовления процессоров для персональных компьютеров двух ведущих фирм мира – Intel и AMD. Фирма  Intel традиционно лидирует,  фирма  AMD традиционно выступает в роли догоняющего: 45-нанометровый процесс покорился ей лишь год спустя после того, как он был освоен корпорацией Intel, а первые процессоры AMD с разрешением 32 нм появились лишь в 2011 году, когда фирма Intel уже перешла  на следующий, 22-нанометровый техпроцесс. В 2014 г. фирма Intel начинает выпуск процессоров по 14 нм технологии.

Рис. 1. Временной разрыв между фирмами Intel и AMD по переходу на новые технологические процессы.

Структуры процессоров Intel

Согласно концепции развития «Tick-Tock» фирма  Intel каждый год меняет либо технологию производства процессоров, либо их структуру (рис. 2).

В 2006  году   представлены процессоры со структурой Core 2 (Merom).

В 2008  году  представлены процессоры со структурой Nehalem.

В 2010  году представлены процессоры со структурой Sandy Bridge.

В 2011  году представлены процессоры со структурой Ivy Bridge.

В 2012  году представлены процессоры со структурой Haswell.

Рис. 2.

Структурная блок-схема одного ядра процессора на базе структуры Core 2 (Merom)

Рис. 3.

Структура Nehalem

Основные отличительные черты процессоров Nehalem

Два, четыре или восемь ядер;
Усовершенствованные по сравнению со структурой
Core 2 (Merom) вычислительные ядра;
Технология SMT, позволяющая исполнять одновременно два  потока на одном ядре;
Три уровня кэш-памяти: L1 кэш размером 64 кбайта на каждое ядро, L2 кэш размером 256 кбайт на каждое ядро, общий разделяемый L3 кэш размером до 24 Мбайт;
Интегрированный контроллер памяти с поддержкой нескольких каналов DDR3 SDRAM;
Монолитная конструкция – процессор состоит из одного полупроводникового кристалла;
Технологический процесс с нормами производства 45 нм;
Возможность интегрирования в процессор графического ядра;
Новая шина QPI с топологией точка-точка для связи процессоров между собой;
Модульная структура.

Структура ядра процессора

Ядро процессоров семейства Nehalem – по сравнению с процессорами со структурой Core  2 изменилось незначительно.

Рис. 4.

Впрочем, определённые улучшения в глубине процессорного ядра всё же были сделаны. При их разработке исходили желания добиться лучшей эффективности ядер Nehalem, позволяющей этому процессору более рационально задействовать все ресурсы. При этом,  все изменения делались с оглядкой на тепловыделение – поэтому процессоры этого поколения стали  более привлекательными с точки зрения соотношения «производительность на ватт».

В соответствии с этой философией в первую очередь модификация затронула декодеры. Напомним, процессоры с структурой Core 2 (Merom) имели в своём распоряжении четыре декодера: три для простых команд и один – для сложных. При этом максимальное число команд, которые декодируют эти процессоры за один такт, достигало 5.

В процессорах со структурой Nehalem декодирование пяти, а не четырёх команд за такт происходит  в большем числе случаев, чем в их предшественниках.

Следующее усовершенствование, связанное с повышением продуктивности начальной части исполнительного конвейера, коснулось блока Loop Stream Detector. Этот блок появился впервые в процессорах с структурой Core 2 (Merom) и предназначался для ускорения обработки циклов. Определяя в программе циклы небольшой длины, блок Loop Stream Detector сохранял их в специальном буфере, что давало возможность процессору обходиться без их многократной выборки из кэша и предсказания переходов внутри этих циклов. В процессорах со структурой Nehalem блок Loop Stream Detector стал ещё более эффективен благодаря его переносу за стадию декодирования команд. Иными словами, теперь в буфере блока Loop Stream Detector сохраняются циклы в декодированном виде, из-за чего этот блок стал несколько похож на блок Trace Cache процессоров Pentium 4. Однако, блок Loop Stream Detector в структуре Nehalem – это особенный кэш. Во-первых, он имеет очень небольшой размер, всего 28 микроопераций, во-вторых, в нём сохраняются исключительно циклы.



Рис. 5.

Улучшен механизм предсказания переходов. В дополнение к уже имеющемуся блоку предсказания переходов был добавлен ещё один «предсказатель» второго уровня. Он работает медленнее, чем первый, но зато благодаря более вместительному буферу, накапливающему статистику переходов, обладает лучшей глубиной анализа.

Данное усовершенствование вряд ли даст сильный выигрыш в типичных приложениях, исполняемых на ПК. Зато при серверной нагрузке двухуровневый блок предсказания переходов может оказаться очень эффективным.
      Другое улучшение результативности механизма предсказания переходов было сделано переделкой блока Return Stack Buffer. На этот блок возлагается задача правильного предсказания адресов возврата из функций. Однако процессоры предыдущего  поколения могли неверно предсказывать адреса возвратов из функций, например, при работе рекурсивных алгоритмов и переполнении соответствующего буфера. Новый же блок Return Stack Buffer, реализованный в структуре Nehalem, эту проблему успешно устранил.

Исполнительные устройства  ядер процессоров со структурой Nehalem не изменились.

Рис. 6.

Также как и процессоры со структурой Core 2 (Merom), процессоры со структурой Nehalem способны отправлять на выполнение до шести микроопераций одновременно. Но в них увеличены размеры внутренних буферов стадии выполнения команд. В результате, процессоры со структурой Nehalem способны держать в ожидании выполнения в Reorder Buffer до 128 микроопераций – а это на 33 % больше, чем в структуре Core 2 (Merom). Соответственно, блок Reservation Station, отправляющий микрооперации непосредственно на исполнительные устройства, расширен с 32 до 36 команд, а кроме того, увеличена и вместимость буферов и для работы с данными.

Ядра  процессоров Nehalem поддерживают технологию SMT и способны исполнять одновременно по два вычислительных потока, нуждающихся в разделении ресурсов друг с другом. В процессорах Pentium 4, где эта же технология преподносилась под  именем Hyper-Threading, её включение давало средний прирост производительности на уровне 10 %. Процессоры со структурой Nehalem обеспечивают с  SMT больший выигрыш. Во-первых, они имеют в своём распоряжении подсистему памяти с гораздо более высокой пропускной способностью, которая способна эффективнее обеспечивать два вычислительных процесса потоками данных. Во-вторых, процессоры Nehalem имееть более «широкую» структуру, позволяющую обрабатывать большее число команд одновременно.


Рис. 7.

Реализация SMT в процессорах со структурой Nehalem, как  и в процессорах Pentium 4, не потребовала существенного увеличения сложности процессора. Продублированы в ядре, фактически, лишь процессорные регистры и Return Stack Buffer. Все остальные ресурсы при включении SMT разделяются в процессоре между потоками динамически (например, Reservation Station или кэш-память) либо жёстко пополам (например, Reorder Buffer).

Активация SMT иногда может приводить и к снижению производительности, поэтому  физические и логические ядра сделаны различимыми и неполноправными, позволяя программистам при необходимости самостоятельно решать вопрос о более правильном задействовании их ресурсов.

Для иллюстрации практическиго влияния описанных изменений на производительность в таблице 1 представлены результаты тестов в сравнении процессоров со структурами Nehalem и Core 2 (Merom) Penryn в нескольких простых синтетических тестах из пакета SiSoftware Sandra 2009. Ценность этих тестов заключается в том, что они совершенно не критичны к параметрам подсистемы памяти, что позволяет, основываясь на их показаниях, делать выводы о собственно процессорной структуре.

           Таблица 1.


Преимущество  структуры Nehalem хорошо видно при включении SMT. Тесты Sandra 2009 качественно оптимизированы под многопоточность, поэтому совершенно не удивительно, что активация SMT улучшает показатели процессоров со структурой Nehalem на величину от 15 до 60 процентов. Однако если сравнивать результаты семейств Nehalem и Penryn, не беря в расчёт SMT, то получается, что процессор со структурой Nehalem способен показать лучшие результаты далеко не всегда. Всё зависит от характера нагрузки, что указывает на отсутствие революционных и универсальных улучшений в недрах нового ядра.

TLB и кэш-память

Наибольшие отличия процессоров со структурой  Nehalem от предшественников следует искать  в интерфейсах и общей структуре.

Существенно увеличен размер TLB (Translation-Lookaside Buffer) – это высокоскоростной буфер, который используется для установления соответствия между виртуальными и физическими адресами страниц. Увеличение размера TLB позволяет повысить число страниц памяти, которые могут быть одновременно использованы без дополнительных дорогостоящих преобразований по таблицам трансляции адресов, находящимся в обычной памяти.

TLB в процессорах со структурой  Nehalem стал двухуровневым. Фактически, к унаследованному от процессоров Core 2 TLB   добавлен ещё один буфер второго уровня. При этом новый L2 TLB имел не только высокую вместительность, позволяющей сохранять до 512 записей, но и сравнительно низкую латентность. Ещё одна особенность L2 TLB заключается в том, что он унифицирован и способен преобразовывать  адреса страниц любого размера.

Изменения в системе TLB сделаны в первую очередь с прицелом на серверные приложения, активно оперирующие большими объёмами памяти. Однако и при выполнении  программ для персональных компьютеров (ПК) увеличенное число вхождений TLB может оказать положительное влияние на быстродействие подсистемы памяти. Тем более, что при активации технологии SMT TLB обоих уровней динамически разделяется между виртуальными ядрами, так что возможность сохранять в этом буфере дополнительные записи явно не будет лишней.

Ещё одно нововведение, способное поднять скорость работы с подсистемой памяти в процессорах с структурой Nehalem, заключалось в значительном ускорении работы команд, оперирующих невыровненными по строкам кэш-памяти данными. Первые робкие шаги в этом направлении были сделаны ещё в ядрах Core 2 (Penryn), но именно в структуре  Nehalem был получен превосходный результат. Теперь SSE-команды, использующие в качество операндов выровненные 16-байтовые последовательности данных, работают с одинаковой скоростью, вне зависимости от того, какой вариант команды используется: для выровненных или для невыровненных данных. Поскольку большинство компиляторов транслирует код с использованием «невыровненных» версий команд, описанное усовершенствование  положительно повлияло на скорость работы многих приложений, оперирующих медиа-контентом.

В процессорах со структурой  Nehalem изменилась структура кэш-памяти. От  двухуровневой структуры кэш-памяти с общим на каждые два ядра L2 кэшем в процессорах со  структурой  Core 2 остался  только кэш первого уровня суммарным объёмом 64 Кбайта, который разделен на две равные части на области для хранения команд и данных. При этом, хотя строение L1 кэша в структуре Nehalem и осталось старым, его латентность (задержка) по сравнению с L1 кэшем Core 2 увеличилась на 1 такт. Произошло это в связи с внедрением в новых процессорах более агрессивных энергосберегающих режимов но, по мнению фирмы Intel, незначительно сказывается на итоговой производительности.

Использование же разделяемого L2 кэша, который показал себя очень эффективным решением в двухъядерных процессорах с структурой Core 2, оказалось весьма проблематичным при увеличении количества ядер. Поэтому в структуре Nehalem, с наличием в процессоре до 8 ядер, кэш второго уровня не является разделяемым. Каждое из ядер получило свой собственный L2 кэш со сравнительно небольшим объёмом 256 Кбайт. Зато благодаря своей ограниченной ёмкости, этот кэш может похвастать в полтора раза более низкой латентностью, чем L2 кэш процессоров со структурой Core 2. Это отчасти компенсирует возросшую латентность (задержку) L1 кэша в структуре Nehalem.

К двум уровням кэша в структуре Nehalem добавился и L3 кэш, который объединяет ядра между собой и является разделяемым. В результате, L2 кэш выступает буфером при обращениях процессорных ядер в разделяемую кэш-память, имеющую достаточно большой объём  8 Мбайт.


Рис. 8.

По сравнению с процессорами AMD со структурой K10,  кэш-память процессоров Nehalem устроена совершенно по-другому.

Во-первых, L3 кэш в процессорах со структурой  Nehalem работает на более высокой частоте.

Во-вторых, кэш L3  инклюзивный, то есть  данные, хранящиеся в кэшах первого и второго уровней, имеются и в L3 кэше. Инклюзивный разделяемый кэш способен обеспечить в многоядерных процессорах более высокую скорость работы подсистемы памяти за счёт избыточного дублирования содержимого L1 и L2 кэшей всех ядер. В частности, при отсутствии в нём запрашиваемых одним из ядер данных, нет необходимости искать их в индивидуальных кэшах других ядер. А благодаря тому, что каждая строка L3 кэша снабжена дополнительными признаками (флагами), указывающими владельцев этих данных, не вызывает затруднений и процедура обратного изменения содержимого строки кэша. Так, если какое-то ядро модифицирует данные в L3 кэше, изначально принадлежащие другому (или другим) ядрам, то в этом случае обновляется содержимое L1 и L2 кэшей и этих ядер. Таким путём решается и проблема с избыточным межъядерным трафиком, направленным на поддержание когерентности инклюзивной кэш-памяти.

Измерения латентности кэш-памяти процессора Nehalem  говорят о высокой эффективности предложенной схемы.

                                  Таблица 2.


L2 кэш процессора  Nehalem действительно обеспечивает крайне невысокую латентность. Кэш третьего уровня также  показавает очень хорошее время доступа, несмотря на свой относительно большой размер.

В процессорах сохранились алгоритмы работы блоков предварительной выборки, они в  структуре  Nehalem целиком позаимствованы из структуры Core 2. Упреждающая выборка данных и команд производится только в кэш-память первого и второго уровня. Тем не менее, даже при использовании старых алгоритмов, результативность работы блоков предварительной выборки улучшилась. Объясняется это тем, что L2 кэш в структуре Nehalem индивидуален для каждого ядра, а при такой организации кэш-памяти гораздо легче отслеживать шаблоны в обращениях. Кроме того, благодаря появлению L3 кэша работа блока предварительной выборки не наносит существенного ущерба пропускной способности шины оперативной памяти. Именно поэтому в серверных вариантах процессоров со структурой   Nehalem блоки предварительной выборки больше не отключаются, как это делалось в процессорах Xeon, основанных на структуре Core 2.

Интегрированный контроллер памяти

Структура Nehalem стала первой  структурой фирмы Intel  с  встроенным  контроллером оперативной памяти. Предусмотрена возможность не только включать или отключать поддержку буферизированных модулей, но и варьировать число каналов и скорость памяти.

Основное преимущество переноса контроллера памяти в процессор заключается не столько в росте пропускной способности, сколько в уменьшении латентности (задержки) подсистемы оперативной памяти. Контроллер работает с DDR3-памятью, которая имеет относительно высокую латентность, но задержки при обращении процессора со структурой  Nehalem в оперативную  память  в любом случае ниже, чем в системах, с процессорами со структурой   Core 2, и использующих память DDR3  (и DDR2).

На пути между процессором и оперативной памятью в системах в процессорами со структурой  Nehalem нет никаких промежуточных устройств, в то время как ранее за работу с оперативной памятью отвечал северный мост чипсета, который вносил собственные весьма существенные задержки, вызванные необходимостью синхронизации шин памяти и FSB.

Ещё одно косвенное преимущество встроенного в процессор памяти заключалось в том, что его функционирование теперь не зависит ни от чипсета, ни от материнской платы. В результате, процессоры со структурой  Nehalem  показывают одинаковую скорость работы с оперативной памятью при работе в платформах различных разработчиков и производителей.

Шина QPI

Многопроцессорные системы, построенные на процессорах со встроенными контроллерами памяти, должны использовать «распределенную» модель памяти NUMA (Non-Uniform Memory Access), а, следовательно, нуждаются в прямом и высокоскоростном соединении между процессорами.

Для решения этой задачи был реализован специальный последовательный интерфейс QPI (QuickPath Interconnect). Интерфейс QPI  (рис. 9)представляет собой два 20-битных соединения, с передачей данных в прямом и обратном направлении. 16 бит в каждом направлении предназначаются для передачи данных, оставшиеся четыре – носят вспомогательный характер, они используются протоколом и коррекцией ошибок.


Рис. 9. Структура шины QPI.


В зависимости от рыночного ориентирования, процессоры с структурой Nehalem  комплектуются одним или несколькими интерфейсами QPI. В итоге в многопроцессорной системе каждый из процессоров может иметь прямую связь со всеми остальными процессорами для снижения латентности при обращении к оперативной памяти, подключенной к «чужому» контроллеру. Модели же для однопроцессорных настольных систем имеют  единственный интерфейс QPI, который  используется для связи с набором логики материнской платы (рис. 10).


Рис. 10. Структуры компьютеров с разным количеством процессоров.

Управление питанием и Turbo-режим


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

Именно поэтому структура Nehalem имеет в процессоре ещё один важный блок – PCU (Power Control Unit). Это  встроенный в процессор программируемый микроконтроллер (то есть, по сути процессор в процессоре), целью которого является «интеллектуальное» управление потреблением энергии. PCU имеет достаточно сложную конструкцию: на его реализацию ушёл примерно 1 миллион транзисторов.



Рис. 11.

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

Общие для всех ядер блоки, такие как контроллеры оперативной памяти и контроллеры интерфейсов QPI переходят в энергосберегающие состояния, когда в состоянии сна находятся все процессорные ядра.

Технология Turbo Boost Technology вводит понятие турбо-режима, в котором отдельные ядра могут работать на частоте, превосходящей номинальную. Основной принцип Turbo Boost Technology состоит в том, что при переходе отдельных ядер в энергосберегающие состояния снижается общее энергопотребление и тепловыделение процессора, а это в свою очередь позволяет нарастить частоты остальных ядер без риска выйти за установленные рамки TDP.


Рис. 12. Принцип действия  технологии  Turbo Boost

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

Большим преимуществом Turbo Boost Technology является его полная прозрачность для операционной системы. Эта технология реализована исключительно аппаратными средствами и не требует использования никаких программных утилит для своей активации.

Полная структура  ядра приведена на рис. 13.

Рис. 13. Структура  ядра Nehalem.

Структура Sandy Bridge

Процессоры со структурой  Sandy Bridge:

имеют 4,6,8 64-битных ядер;  

каждое ядро:

обеспечивает:

внеочередное выполнение команд;

поддержку двух потоков,

может выполнять  четыре команды за такт;

поддерживает 3- и 4-х операндные (128/256-битные) векторные команды  расширенного набора AVX (Advanced Vector Extensions);

в процессоре имеется:

встроенное графическое ядро;

интегрированный контроллер памяти DDR3;

кольцевая шина;

процессор выполнен с соблюдением норм  32-нм технологического процесса.

Поколение процессоров со структурой Sandy Bridge называют вторым поколением процессоров со структурой Core 2.

Упрощенная блок-схема ядра со структурой Sandy Bridge

Общая структура Sandy Bridge приведена на рис. 1 и 2.

Рис. 1. Общая структура ядрк Sandy Bridge.

Рис. 2. Общая структура ядра Sandy Bridge.

Фронт конвейера

На рис. 3 приведена структура фронта ковейера ядра процессора Sandt Bridge.

Рис. 3.     Фронт конвейера. Цвета показывают разные виды информации и обрабатывающих или хранящих её блоков.

Кеш команд L1 ядра со структурой Sandy Bridge размером 32 Кбайт обладает восьмиканальной (8-way) ассоциативностью. После упреждающей выборки и предварительного декодирования команды  подаются на декодеры, которые, в свою очередь, выдают на выходе микрооперации фиксированной длины для дальнейшей обработки с изменением последовательности (out-of-order). В полной аналогии с ядром со структурой Nehalem, три из четырёх декодеров ядра со структурой Sandy Bridge обрабатывают простые команды, в результате чего каждый выдаёт по одной микрооперации на выходе, в то время как четвёртый декодер обрабатывает сложные команды и выдаёт до четырёх микроопераций. Кроме того, микропрограммные инструкции размером более четырех микроопераций разбиваются на блоки по четыре микрооперации.

В полной аналогии с предыдущими поколениями процессоров, блоки декодирования в структуре Sandy Bridge поддерживают как микрослияния (Micro Fusion), объединяющие несколько команд в ряд одиночных микроопераций, так и макрослияния (Macro Fusion), объединяющие пары команд в одну микроинструкцию. В любом случае, декодеры структуры Sandy Bridge, как и декодеры структуры Nehalem, вне зависимости от характера поступающих команд выдают на выходе не более четырех микроопераций за такт.

Одним из наиболее важных нововведений в структуре Sandy Bridge является кеш декодированных микроопераций, или кеш команд L0. По сути своей кеш декодированных микроопераций напоминает трассировочный кеш структуры  NetBurst (Pentium 4), однако принцип работы у них совершенно разный, сходство заканчивается на том, что оба они работают с микрооперациями.

Благодаря структурной организации формата 32х8 с возможностью хранения шести микроопераций в линии, кеш декодированных микроопераций вмещает чуть более полутора тысяч микроопераций. Без особых затей он кеширует на выходе декодеров все предварительно декодированные микрооперации. Как только поступает на обработку новая инструкция, блок упреждающей выборки первым делом производит сверку с кешем L0, и в случае обнаружения совпадений, загрузка конвейера по четыре микрооперации за такт в обход декодеров осуществляется уже из кеша L0. Незадействованные и простаивающие цепи декодеров, кстати, весьма сложные, и потому достаточно «прожорливые», в этот момент попросту отключаются от питания. В противном случае, когда кеш декодированных операций оказывается невостребованным, продолжается обычная работа по выборке и декодированию команд, а кеш декодированных операций переводится в режим экономии энергии.

Кеш L0 в какой-то мере можно считать частью кеша L1, в который он, кстати, интегрирован, но отдельной и очень быстрой его частью. При работе с большинством  приложений, вероятность удачного «попадания» в кеш декодированных микроопераций очень велика и может достигать 80%.

Ничуть не меньше изменился блок предсказания ветвлений (branch prediction). В частности, буфер предсказания результата ветвления (branch target buffer, BTB) ядра со структурой Sandy Bridge вмещает в два раза больше адресов результатов ветвления и вдвое большую историю комбинаций команд, нежели аналогичный буфер в ядре со структурой Nehalem. Кроме того, увеличены размеры области хранения истории ветвлений, в том числе предсказанных и выполненных. Так, удалось снизить количество неудачных предсказаний ветвлений, что положительно отозвалось как на увеличении производительности за счёт уменьшения времени вынужденного простоя для сброса конвейера с десятками обработанных впустую команд, так и на потреблении энергии, затрачиваемой зря на обработку неудачных ветвлений.

Предсказание переходов

Предсказатель переходов (BPU)  полностью переработан. Как и в структуре Nehalem, он каждый такт (и до реального выполнения) предсказывает адрес следующей 32-байтовой порции программы в зависимости от предполагаемого поведения команд перехода в только что предсказанной порции — причём, вне всякой зависимости от числа и типа переходов. Точнее, если в текущей порции есть предположительно срабатывающий переход, выдаются его собственный и целевой адреса́, иначе — переход к следующей подряд порции. Сами предсказания стали ещё точней за счёт удвоения буфера целевых адресов (BTB), удлинения регистра глобальной истории переходов (GBHR) и оптимизации хэш-функции доступа к таблице шаблонов поведения (BHT). Правда, фактические тесты показали, что в некоторых случаях эффективность предсказания всё же чуть хуже, чем в структуре Nehalem.

Декодирование и IDQ

Предсказанные наперёд адреса исполняемых команд (попеременно для каждого потока — при включенной технологии Hyper-Threading) выдаются для проверки их наличия в кэшах команд (L1I) и мопов (L0m).

Из L1К порция попадает в буфер предекодера, а оттуда — в сам предекодер-длиномер (ILD), обрабатывающий до 7 или 6 команд/такт (с и без макрослияния, но всё равно на 1 больше, чем в структуре Nehalem) в зависимости от их совокупной длины и сложности.

Размеченные команды попадают в одну из двух очередей декодера (IQ), по одной на поток, на 18 ячеек каждая). Декодер читает команды из очереди и переводит их в мопы. В нём есть 4 простых транслятора (переводят 1 команду в 1 моп, а с макрослиянием — 2 команды в 1 моп), сложный транслятор (1 команда в 2–4 мопа) и микросеквенсер для самых сложных команд, требующих 5 и более мопов из микрокода. Результат декодирования поступает в кэш мопов и две очереди мопов (по одной на поток). Последние (официально именуемые IDQ — instruction decode queue, очередь декодированных команд) по прежнему имеют по 28 мопов и возможность блокировки цикла, если его исполняемая часть там уместится.

Декодер научили обрабатывать новые команды поднабора AVX.

Формирование потока команд с изменением последовательности

Процессы распределения, переименования, планировки и вывода данных в процессе конвейерного выполнения макроопераций в структуре Sandy Bridge подверглись самой значительной переработке.

 Реализация алгоритма выполнения команд с изменением последовательности в предыдущих поколениях процессоров  Core, вплоть до Westmere,  базировалась на использовании буфера переупорядочивания - ROB (reorder buffer), который в конечном итоге также служил для восстановления последовательности команд. По структуре этот буфер представляет собой матрицу с записями всех исполняемых в данный момент команд, а также гигантский массив виртуальных данных со значениями регистров и информацией о перемещениях между регистрами.

 Теперь, в структуре Sandy Bridge, результаты отслеживания и переименования микроопераций фиксируются с помощью физического регистрового файла, PRF (physical register file), присущего структуре  NetBurst  (Pentium 4) и также характерного для многих Out-of-Order структур вроде структуры фирмы AMD Bulldozer/Bobcat, IBM POWER, но отсутствующего в ядрах структуры Nehalem. Фактически, на буфер переупорядочивания в ядре структуры Sandy Bridge возложена только функция «трассировки» команд, обрабатываемых в данный момент времени, в то время как функции хранения данных возложены на независимый физический регистровый файл. Иными словами, факт выполнения операции в Out-of-Order структуре Sandy Bridge приводит только к тому, что регистр указывает на иное значение в PRF, а не к переносу 32-, 64-, 128- или 256-битных данных, как в случае, когда используется только буфер переупорядочивания.

В таблице 1 приведены сравнительные данные для трех структур.

Таблица 1.

Ёмкость компонентов исполнительного Out-of-Order кластера

Поколение структур Intel

Core  Merom

Nehalem

Sandy Bridge

Буфер переупорядочивания - ROB (Re-Order Buffer)

96

128

168

Физический регистровый файл - Physical Register File (PRF),  Integer

-

-

160

Физический регистровый файл - Physical Register File (PRF),  FP/Vector

-

-

144

Буфер декодированных, но ещё не выполненных команд - Reservation Station (RS)

32

36

54

Буферы записи - Load Buffers

32

48

64

Буферы чтения - Store Buffers

20

32

36

Распределение процессов между двумя структурами вместо одной может показаться структурным ретроградством, ведущим к усложнению конструкции и дополнительному увеличению количества транзисторов, то есть, к росту энергопотребления процессора. Тем не менее в конечном итоге такое разделение функций значительно разгружает буфер переупорядочивания, постоянно перегруженный в процессорах Nehalem и от того постоянно «горячий».  

Кроме появления в структуре Sandy Bridge физического регистрового файла, изменились и характеристики традиционных модулей кластера Out-of-Order процессов. Так, буфер  переупорядочивания способен обрабатывать до 168 микроопераций одновременно. Целочисленный физический регистровый файл Sandy Bridge хранит 160 отдельных 64-битных записей; физический регистровый файл для векторно-вещественных данных с плавающей запятой хранит 144 56-битных записи, то есть регистры YMM с новыми векторными x86-64 командами AVX целиком.

Исполнительные блоки

Как и раньше, в процессорах со структурой  Nehalem, загрузка микроопераций всех типов: SIMD, целочисленных и с плавающей запятой, происходит  по одинаковому сценарию, единым унифицированным планировщиком, динамически распределённым между всеми потоками. Разница в том, что в структуре Sandy Bridge планировщик более ёмкий и загружается сразу 54 переименованными и готовыми к выполнению микрокомандами.

Благодаря существенной доработке, нацеленной на удвоение производительности при работе с 256-битными векторными командами AVX и возможности выполнения большинства из них как единой микрооперации, исполнительные блоки ядер структуры Sandy Bridge стали вдвое мощнее, чем у ядер со структурой  Nehalem. Теперь они способны обрабатывать восемь операций двойной точности с плавающей запятой (FP) или 16 FP-операций одинарной точности за такт. Таким образом,  ядро Sandy Bridge способно исполнять за каждый такт 256-битные FP-умножение и FP-сложение сложение чисел с поавающей точкой  и 256-битное смещение.

Несмотря на увеличение разрядности исполнительных блоков ядра до 256 бит, увеличения ширины шины данных до 256 бит не произошло. Для выполнения 256-битных микроопераций в ядре со структурой Sandy Bridge объединяются возможности имеющихся в наличии 128-битных трактов для работы с данными SIMD INT и SIMD FP.

 

 

Рис. 4.

Также стоит упомянуть, что в ядре со структурой Sandy Bridge повышена производительность при обработке команд стандарта шифрования AES и RSA, а также производительность при вычислении хешей SHA-1.

Подсистема памяти

Необходимость работы с вдвое увеличенными (до 256 бит) операндами SSE FP не могла не сказаться на нагрузке подсистемы памяти ядра со структурой Sandy Bridge, которая должна обслуживать не менее двух запросов за такт, гарантированно обеспечивая возможность 16-байт записи и 16-байт чтения.

 

 

Рис. 5.

Вот почему в структуре 8-банкового кеша данных L1 ядра со структурой Sandy Bridge был добавлен второй 16-битный порт чтения, благодаря которому суммарная пропускная способность кеша выросла до 48 байт за такт: два 16-байт запроса чтения и 16-байт запись. Размеры буферов  записи и чтения, разделённых между исполнительными блоками ядра со структурой Sandy Bridge, были также увеличены: буфер записи - до 64 ячеек, буфер чтения - до 36 ячеек.

 

 Рис. 6.

8-банковый ассоциативный кеш L2 структуры Sandy Bridge, распределённый по 256 Кбайт на каждое ядро практически не изменился по сравнению с предыдущей структурой Nehalem.

 

Hyper-Threading

Стадии конвейера разделяются между потоками следующим образом:

Дублируются: TLB L1I для страниц по 2 МБ, IQ, RSB, IDQ, архитектурное состояние ядра, АРФ для старших половин регистров Уmm;

Делятся пополам: TLB L1I для страниц по 4 КБ, L0m, ROB, обе очереди в LSU, буфер простого предзагрузчика в L1;

Делятся динамически: BTB, резервация, все ФУ, вся подсистема памяти (кроме её блоков, указанных выше);

Чередуются по тактам (кроме случаев срыва одного из потоков): все стадии фронта, размещение мопов в планировщике и отставка.

«Делятся динамически» - это значит, что блок не знает о существовании двух потоков и никак бы не изменился, если бы в ядре не было многопоточности. Это особенно наглядно в случае планировщика: ROB делится между потоками, т. к. надо соблюдать очерёдность размещений и отставок соответственно адресам каждого потока. Но когда мопы попадают в резервацию, адресов в них уже нет, а есть номера ячеек в ROB и ФРФ. Учитывая, что некий регистр-приёмник N при переименовании получит в одном потоке физический регистр X, а в другом — Y (что равносильно двум записям в N в одном потоке), то резервации всё равно, чьи мопы одновременно запускать, а для функциональных устройств (ФУ) всё равно, чьи исполнять.

Наличие дублируемых и статически делящихся пополам ресурсов и чередование потоков по всей поочерёдной части конвейера говорит о том, что лучше всего структуры Nehalem и Sandy Bridge чувствуют себя при выполнении пары почти одинаковых по объёму команд потоков. Причём если это 2 одинаковых потока, то обеспечить загрузку разных ФУ и прочих динамически разделяемых блоков будет трудно — общий алгоритм будет спотыкаться примерно в тех же местах, даже работая с разными данными. А подобрать две разные программы с примерно одинаковом темпом использования команд может оказаться ещё труднее — тем более, что это всецело зависит от ядра ОС, которая почти ничего не знает о внутренних событиях аппаратного ядра и загрузке его блоков.

Возможно,  динамическое разделение в TLB L1I не используется (как в остальных TLB, особенно, учитывая, что сам кэш L1I разделяется так же), потому что его нет и у кэша мопов, а эти две структуры при вытеснении срабатывают одновременно. Впрочем, глядя на список пункта «Делятся пополам» (а в этих блоках, напомним, 3 цифры размеров из 4 в Sandy Bridge  увеличились), можно сделать вывод, что ускорение от включения HT если не увеличится, то хотя бы с меньшей вероятностью станет отрицательным, что изредка бывало в структуре  Nehalem.

Кэш L3

Физически, кэш L3  разделён на банки по числу ядер. В структуре Nehalem была возможность сделать запись и чтение в/из кеша L3 за такт, если они попадали в разные банки, т. к. использовался общий коммутатор и контроллер на весь кэш. Теперь организация банков другая: можно сделать запись или чтение, но в каждом банке по отдельности. А т. к. число банков почти всегда равно числу ядер (исключения  встречались только у 6–10-ядерных серверных Xeon, где в некоторых моделях банков на 1 больше или меньше числа ядер), то это фактически линейно увеличивает пропускную способность кеша L3. Учитывая, что она разделяется между всеми ядрами (включая графический процессор), это очень полезно, т. к. пропуск, приходящийся на каждое ядро, до сих пор был главной проблемой любого разделяемого кэша.

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

Как и процессоры со структурой Nehalem,  ядра процессоров со структурой  Sandy  Bridge активней используют КМОП-логику по сравнению с динамической, что отразилось на частоте возникновения ошибок при работе. Это потребовало внедрить более мощные алгоритмы и коды обнаружения и коррекции ошибок (ECC) в кэшах ядер, способные в каждом байте обнаружить и исправить 2-битные ошибки и обнаружить (но не исправить) 3-битные. До сих пор ядра умели обнаруживать до двух неверных бит и исправлять один, требуя в среднем 1 бит ECC на каждый защищаемый байт. Новый код требует не менее 1,5 бит/байт .

Главное изменение в кеше L3 — он стал работать на полной частоте ядра. Точнее, целочисленных ядер. Точнее, наиболее быстрого из них в каждый момент, т. к. часть ядер могут спать или быть недогруженными с частотой между минимумом и максимумом. Помимо увеличения пропускной способности это ещё и уменьшает задержки, которые, разумеется, меряются тактами ядер на их частоте. И вот (см. таблицу с параметрами кэша) в структуре Sandy Bridge  они уменьшились на 30%. Это при том, что сама частота кэша вовсе не подросла на 30%. Причина в том, что когда поток данных пересекает силовые (по величине логических «0» и «1» в вольтах) и, особенно, частотные домены, происходит задержка в несколько тактов для преобразования уровней и совпадения фронтов тактовых сигналов. В структуре Sandy Bridge  такой проблемы нет, т. к. кеш L3 работает на том же напряжении, что и работающие ядра (не отключенные силовыми ключами), а частота у всех активно загруженных ядер всегда одинакова (включая применение технологии Turbo Boost) — и именно на неё и настроится частота кешаL3.

Как и в структуре Nehalem, каждый банк кеша L3 разделён на блоки по 512 КБ и 4 пути. В большинстве процессоров в каждом банке таких блоков 3 или 4. Серверные процессоры  Xeon имеют 6, 8 или 10 ядер и банков кеша L3, но последние увеличены как по размеру (до 3 МБ), так и по ассоциативности (до 24), что в самых дорогих процессорах  даёт  30 МБ.

Кольцевая шина (Ring Interconnect)

Вся история модернизации процессорных структур фирмы Intel последних лет неразрывно связана с последовательной интеграцией в единый кристалл всё большего количества модулей и функций, ранее располагавшихся вне процессора: в чипсете, на материнской плате и т.д. Соответственно, по мере увеличения производительности процессора и степени интеграции процессора, требования к пропускной способности внутренних межкомпонентных связей  росли опережающими темпами. До поры до времени, даже после внедрения графического процессора в структуру процессоров  Arrandale/Clarkdale, удавалось обходиться межкомпонентными связями  с привычной перекрёстной топологией - этого было достаточно.

В результате усиления интеграции, фирме Intel пришлось изменить работу с кэшем третьего, последнего, уровня. Во времена, когда потолком были четырёхядерные процессоры Bloomfield, Lynnfield и Clarkdale (и даже шестиядерные Westmere), каждому физическому ядру можно было обеспечить собственное соединение с этим общим кэшем. Технических проблем это не вызывало. Но уже процессоры серии Xeon 7500   содержали до восьми физических ядер на процессор и будь они построены по прежнему принципу, возникало бы непомерное количество обращений между основным и последним уровнями кэш-памяти. Поэтому, фирма  Intel адаптировала  для новой структуры кольцевую шину (ring bus), что в промышленных решениях позволило наращивать количество ядер в процессоре и дальше, избегая выхода логистики обмена данными из под контроля.

Концепция кольцевой шины также серьёзно упростила создание на базе структуры Sandy Bridge различных кристаллов. К примеру, из   процессора с 4-мя  ядрами, технически очень легко сделать 2-ядерный вариант или добавить/убрать какие-либо блоки в будущем.

Серверные процессоры со структурой Sandy Bridge  основаны на том же проекте кольцевой шины и могут иметь большее число  ядер (например,  10 ядер).

Однако эффективность такой топологии высока лишь при небольшом количестве компонентов, принимающих участие в обмене данными. В структуре Sandy Bridge для повышения общей производительности системы использована  кольцевая топология 256-битной межкомпонентной шины, выполненной на основе новой версии технологии QPI (QuickPath Interconnect), расширенной, доработанной и впервые реализованной в структуре  серверного процессора  со структурой Nehalem-EX (Xeon 7500.

Кольцевая шина в структуре Sandy Bridge для настольных и мобильных систем (Core II) служит для обмена данными между шестью ключевыми компонентами процессора: четырьмя процессорными ядрами, графическим ядром, кешем L3 и системным агентом. Шина состоит из четырёх 32-байтных колец: шины данных (Data Ring), шины запросов (Request Ring), шины мониторинга состояния (Snoop Ring) и шины подтверждения (Acknowledge Ring), на практике это фактически позволяет делить доступ к 64-байтному интерфейсу кеша последнего уровня на два различных пакета. Управление шинами осуществляется с помощью коммуникационного протокола распределённого арбитража, при этом конвейерная обработка запросов происходит на тактовой частоте процессорных ядер, что придаёт архитектуре дополнительную гибкость при разгоне. Производительность кольцевой шины оценивается на уровне 96 Гбайт в секунду на соединение при тактовой частоте 3 ГГц, что фактически в четыре раза превышает показатели процессоров Intel предыдущего поколения.

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

Рис. 6. Блок-схема общей кольцевой шины

Когерентность и «поддержка» OpenCL

В структуре Nehalem впервые  со времён процессора Pentium 4 кэш последнего (т. е. 3-го) уровня стал включающим относительно остальных. Это означает, что в многопроцессорной системе процессорам стало проще отслеживать копии данных, раскиданных по разным кэшам, что требуется для поддержки их когерентности. Для этого теги каждой строки в кеше L3 среди прочего хранят набор битов, обозначающих я́дра этих процессоров, в кэши которых эта строка была скопирована, а также номера других процессоров, в кэшах которых также есть её копия. Для процессоров Westmere-EX число таких битов было не меньше 17 (10 ядер + 7 «остальных» процессоров). Кроме того, тогда же стандартный протокол когерентности MESI обновился до MESIF, включив в себя 5-е состояние Forward, разрешающее ответ на снуп-запрос от другого процессора  (в MESI ответить мог каждый процессор, что увеличивало снуп-трафик). Соображением минимизации снуп-трафика руководствовалась и фирма AMD, добавив для своих процессоров Opteron 5-е состояние Owned и получив протокол MOESI.

Когда при доступе в кеш L3 из какого-либо ядра оказывается, что искомая строка закэширована другим ядром (для простоты предположим, что одним) и может быть им модифицирована, происходит обращение к его кэшам L1D и L2 для проверки её актуального состояния. Проверка называется «чистой», если данные оказались нетронутыми, и «грязной», если они модифицированы и требуют копирования в запрашивающее ядро и кеш L3. В структуре Sandy Bridge  первый случай вызывает задержку в 43 такта, а второй — в 60. Эти указанные в документации цифры почему-то являются константами, хотя должны зависеть от топологического расстояния между ядрами на кольцевой шине. Да и разница в 17 тактов куда больше, чем положенные 2 для передачи 64 байт.

Новинкой в структуе Sandy Bridge  по части включающей политики кеша  L3 было то, что биты присутствия копий данных в кэшах ядер учитывают и графический процессор (ГП). Т. е. с точки зрения программы графический процессор  можно использовать как векторный сопроцессор, работающий с общими данными в общем адресном пространстве.

Для облегчения доступа к данным всё адресное пространство процессора делится на 3 раздела: для x86-ядер, графического процессора и некогерентных данных. Раздел графического процессора использует «слабую» когерентность для ускорения проверок, осуществляемых программным путём через драйвер (в частности, данные пересылаются в раздел x86 синхронизационными процедурами, а не автоматически). Некогерентные данные также используются ГП для завершающих операций переноса готового кадра в память.

Каждый путь в кеше L3 имеет 3 бита атрибутов, указывающих, что содержимое этих строк принадлежит вышеуказанным трём разделам в любой их комбинации. Но для минимизации затрат на поддержку когерентности между разделами протоколы и семантика связности (отличные в каждом из них) применяются, только когда это явно требуется — т. е. когда в одном пути кэшируется область, помеченная как общая для нескольких разделов.

Системный агент и интегрированный контроллер оперативной памяти

Системный агент — это та часть «внеядра», которая получается после вычета кэша L3 и графического процессора. Остаётся:

арбитр со своим портом кольцевой шины — коммутирует потоки данных между остальными частями агента;

порт отладочной шины GDXC;

контроллер шин QPI - присутствует только в серверных моделях;

контроллер шин PCIe 2.0 (на 1 ГП/с) или 3.0 (2 ГП/с, только для процессоров Xeon) — в зависимости от модели может быть 16-, 20-, 24- и 40-полосным и допускает различные схемы соединений по числу полос: для наиболее распространённых 20-полосных моделей это x16+x4 (для большинства мобильных процессоров со структурой Sandy Bridge  доступен только этот вариант), x8+x8+x4 и x8+x4+x4+x4 (только для младших Xeon);

контроллер шины DMI 2.0 — для соединения с «южным» мостом PCH;

«гибкое межсоединение экранов» (Flexible Display Interconnect, FDI) — порт для соединения с контроллером физических интерфейсов экранов в составе «южного» моста;

ускоритель (де)кодирования видео;

контроллер оперативной памяти;

программируемый силовой контроллер (Power control unit, PCU) с собственной программой (прошивкой).

Контроллер оперативной памяти (ИКП)   поддерживает 2–4 канала оперативной памяти. Каждый канал имеет отдельные ресурсы и независимо обслуживает запросы. ИКП имеет внеочередной планировщик операций, максимизирующий пропускную способность (ПСП) с минимизацией задержек. Кроме того, ещё в версиях процессоров со структурой Nehalem для процессоров Xeon появилась технология SMI (Scalable Memory Interconnect, масштабируемое межсоединение памяти) с использованием подключаемых SMB (масштабируемый буфер памяти, аналог буфера AMB из FB-DIMM, но находящийся не на модуле, а на системной плате). Буфер подключается скоростной последовательной шиной к каналу ИКП процессора и позволяет подключить к себе большее суммарное число модулей, чем напрямую к процессору. Правда, от этого ухудшаются и задержки, и частота работы оперативной памяти.

В каждом канале есть 32-строковый буфер записи, причём запись считается завершённой, как только данные попадут в этот буфер. Слиянием записи этот буфер не занимается, в результате чего частичные записи (когда обновляется не вся строка) обрабатываются неэффективно, т. к. требуют чтения старой копии строки. Это странно, учитывая, что современные микросхемы памяти учитывают битовую маску записи не только для отдельных 8-байтовых слов (которых 8 на строку), но и байт в словах, потому комбинация неизменной и обновлённой частей строки производится внутри микросхемы оперативной памяти, а не в ИКП. Впрочем, в структуре Sandy Bridge  ИКП (как и кэши) может включать продвинутые методы ECC, и для этого даже частично обновляемую строку для пересчёта ECC надо начала считать целиком. Причём это правило работает даже при применении обычной оперативной памяти, а также в большинстве мобильных моделей, где ECC-оперативная память вовсе не поддерживается.

Системны агент и управление питанием Turbo Boost 2.0

Этот модуль содержит в себе контроллер оперативной памяти, модуль управления питанием (Power Control Unit, PCU), контроллеры PCI-Express 2.0, DMI, блок видеовыхода. Как и все основные блоки процессора, системный агент также подключен к скоростной кольцевой шине и располагается на одном кристалле с  ядрами.  

Рис. 7.

Контроллер PCI-Express 2.0 обеспечивает 16 линий PCI-e, которые при использовании систем из нескольких дискретных видеоадаптеров могут быть распределены по схеме 8+8 при использовании двух слотов или 8+4+4 при использовании трёх слотов PCI-e x16.

Частью системного агента является контроллер управления питанием (PCU). Он отвечает за динамическое изменение напряжений питания и частот всех основных блоков процессора, причем для ядер процессора и графического ядра управление происходит раздельно.

Такое “близкое” расположение контроллера питания к процессору позволило достаточно сильно усовершенствовать алгоритм технологии Turbo Boost. Теперь, в зависимости от нагрузки, может происходить разгон ядер процессора и графического ядра до уровня, значительно превышающего TDP.

Структура 4-го поколения Haswell

Революции в структуре  Haswell  отсутствуют. Серьезных изменений в вычислительных ядрах не производилось.

Главный упор был сделан на управление энергопотреблением и масштабируемость: эта структура  изначально рассчитана на широкий спектр применений: от планшетов до серверов.

Процессоры со структурой Haswell  производятся по 22-нанометровому техпроцессу, имеют  2-4 ядра, три варианта интегрированной графики Intel HD (GT1, GT2, GT3), различные объемы кэш-памяти и различныеи уровнями энергопотребления.

S0ix – новый набор состояний процессора в зависимости от его текущей загрузки. Собственно, частично он нам знаком по процессорам Atom (Moorestown) второго поколения. Теперь они перекочевали в семейство Core. Основная идея – минимизировать энергопотребление в момент низкой активности или полного бездействия системы, например, когда пользователь просто что-то разглядывает на экране, а в фоновом режиме не выполняется никаких ресурсоемких задач. В этот момент процессор отключает (обесточивает) все свои незадействованные модули даже внутри самих вычислительных ядер. Модули включаются только по необходимости, что в итоге дает аж двадцатикратную экономию в режиме простоя, при этом сама система находится в полностью активном состоянии C0. В итоге идея с полным отключением блоков оказалась в разы эффективнее снижения напряжения и понижения частот. Аналогичным образом оптимизированные и другие состояния C0-C7.

Кроме этого, ядра еще больше "развязываются" друг от друга по частоте, что позволяет эффективнее использовать режимы Turbo, при этом оставаясь в рамках заданного теплового пакета.

Другие технические изменения коснулись системы предсказания ветвлений, которая в презентациях была обозначена как система нового поколения, но повышение ее эффективности в численном виде констатировано не было.

Оптимизирована межъядерная шина. Кроме того, вдвое увеличена пропускная способность кэшей L1 и L2. На каждый такт они теперь оперируют вдвое большим количеством данных, хотя сами объемы кэшей, а также задержки в выборке или в случае кэш-промахов остались аналогичными с предыдущим поколением (таблица 2).

Таблица 2.

Появился расширенный набор команд AVX2, а также существенно увеличилась скорость их выполнения. Также в Haswell появился ранее анонсированный набор инструкций-расширений TSX (Transactional Synchronization Extensions), которые помогут программистам лучше управлять потоками команд и данных для более плотной загрузки многоядерных процессоров.

Сравнение структур Sandy Bridge,  Ivy Bridge, Haswell

Все  привыкли к тому, что чем новее процессор, тем он лучше. И до недавних пор это действительно работало. Улучшались производственные технологические процессы. Это выливалось в рост частотного потенциала и в увеличение сложности процессорных полупроводниковых кристаллов. Возросший транзисторный бюджет расходовался либо на структурные инновации, либо на увеличение количества ядер, или рост объёма кеш-памяти, или на графическую подсистему.

Однако с момента появления процессоров со структурой Sandy Bridge привычная поступь прогресса стала замедляться. Даже несмотря на то, что для производства процессоров со структурой  Sandy Bridge применялся 32-нм техпроцесс, а для более новых Ivy Bridge и Haswell — 22-нм технология, все эти три поколения процессоров имеют сходную многоядерную структуру, работают на очень близких тактовых частотах и располагают одинаковыми объёмами кеш-памяти. Фактически все влияющие на производительность различия теперь оказались заглубленными в недра структуры.

В принципе, в том, что в формальных спецификациях процессоров для настольных персональных компьютеров (ПК) с 2011 года прекратился рост базовых показателей, нет ничего страшного. Как известно из предшествующего опыта, структурные улучшения способны на многое. Тем более что и стрктуры Ivy Bridge, и Haswell — это не простые «тики» в интеловской терминологии. Даже о структуре Ivy Bridge, выход которого был сопряжён со сменой техпроцесса, фирма Intel говорила как о такте «тик+», подчёркивая, что речь идёт не о простом переносе решений структуры Sandy Bridge на новые технологические рельсы, а о комплексной доработке старого дизайна. Haswell же вообще относится к циклу разработки «так», то есть представляет собой новую версию структуры без каких-либо оговорок. Поэтому повышения быстродействия можно было ожидать и от имеющегося развития интеловских процессоров, пусть оно и не сопровождается сменой чисел в списке формальных характеристик.

Однако никакого бурного роста производительности процессоров на самом деле не произошло. Причина состоит в том, что основные усилия интеловских разработчиков направлены не в сторону совершенствования вычислительной мощности — ее более чем достаточно, чтобы оставить конкурентов далеко позади, — а на улучшение параметров, критичных для мобильного рынка. Желая одновременно заткнуть за пояс и гибридные процессоры фирмы AMD, и мобильные процессоры с архитектурой ARM, фирма Intel планомерно оптимизирует тепловыделение и энергопотребление, а также занимается подтягиванием собственного графического ядра. Для «настольных» же процессоров эти параметры малозначимы, поэтому, с точки зрения пользователей «настольных» компьютеров, развитие структур Sandy Bridge → Ivy Bridge → Haswell смахивает на проявление технологического инфантилизма.

Вспомним, что происходило с вычислительными ядрами процессоров начиная с 2011 года, когда на рынке появились первые процессоры со структурой Sandy Bridge c действительно инновационной структурой с полностью переработанной схемой внеочередного исполнения команд. Первоначальный проект Sandy Bridge стал прочным базисом для всех последующих поколений структуры. Именно тогда появились такие ключевые и актуальные до сих пор элементы, как кольцевая шина, кеш декодированных инструкций «нулевого уровня», принципиально новый блок предсказания переходов, схема исполнения 256-битных векторных инструкций и многое другое. После структуры Sandy Bridge интеловские инженеры ограничивались лишь небольшими изменениями и дополнениями, не затрагивая заложенный в этой структуре фундамент.

В вышедших годом позже процессорах семейства Ivy Bridge прогресс коснулся вычислительных ядер в очень небольшой степени. Как фронтальная часть конвейера, рассчитанная на обработку четырёх инструкций за такт, так и вся схема внеочередного исполнения команд сохранились в полностью первозданном виде. Однако производительность Ivy Bridge всё-таки стала немного выше, чем у предшественников. Достигнуто это было тремя небольшими шагами. Во-первых, появилась давно назревшая возможность динамического распределения ресурсов внутренних структур данных между потоками, в то время как ранее все очереди и буферы в расчёте на Hyper-Threading делились на два потока жёстко пополам. Во-вторых, был оптимизирован узел исполнения целого и вещественного деления, в результате чего темп выполнения этих операций удвоился. И в-третьих, задача обработки операций пересылки данных между регистрами была снята с исполнительных устройств, а соответствующие команды стали транслироваться в простое разыменование регистров.

С появлением Haswell вычислительная производительность опять немного подросла. И хотя говорить о качественном скачке нет никаких оснований, набор нововведений выглядит отнюдь не ерундовским. В этом процессорном дизайне инженеры глубоко покопались в средней части конвейера, благодаря чему в Haswell возросло количество исполнительных портов (кстати, впервые с 2006 года). Вместо шести их стало восемь, поэтому в теории пропускная способность конвейера Haswell стала на треть больше. Вместе с тем ряд шагов был предпринят к тому, чтобы обеспечить все эти порты работой, то есть улучшить возможности процессора по параллельному исполнению инструкций. С этой целью были оптимизированы алгоритмы предсказания ветвлений и увеличен объём внутренних буферов: в первую очередь — окна внеочередного исполнения команд. Вместе с тем инженеры Intel расширили систему команд, добавив подмножество инструкций AVX2. Главное достояние этого набора — FMA-команды, объединяющие сразу пару операций над числами с плавающей точкой. Благодаря им теоретическая производительность Haswell при операциях над числами с плавающей точкой с одинарной и двойной точностью выросла вдвое. Не обойдённой вниманием осталась и подсистема работы с данными. Расширение внутреннего параллелизма процессора, как и появление новых инструкций, ворочающих большими объёмами данных, потребовали от разработчиков ускорить работу кеш-памяти. Поэтому пропускная способность L1- и L2-кеша в Haswell по сравнению с процессорными дизайнами предыдущих поколений была удвоена.

Впрочем, пользователи при выходе новых поколений процессоров хотят видеть не столько обширные списки сделанных изменений, сколько увеличившиеся столбики на диаграммах с производительностью в приложениях. Поэтому  теоретические выкладки дополним и результатами практических тестов. Причём для лучшей иллюстративности в первую очередь используем к синтетический бенчмарк, позволяющий увидеть изменение различных вычлененных из общей картины аспектов быстродействия. Для этой цели отлично подходит популярная тестовая утилита SiSoftware Sandra 2013, пользуясь которой сравнены между собой три четырёхъядерных процессора (Sandy Bridge, Ivy Bridge и Haswell), тактовая частота которых была приведена к единому и постоянному значению 3,6 ГГц. Обратите внимание, показатели процессора со структурой Haswell приведены на графиках дважды. Один раз — когда в алгоритмах тестирования не используются новые наборы команд, внедрённые в этом процессорном проекте, и второй раз — с активированными инструкциями AVX2.

Обычный арифметический тест выявляет, что в Haswell произошёл заметный рост производительности целочисленных операций. Увеличение скорости, очевидно, связано с появлением в этой структуре порта, специально отведённого под дополнительное целочисленное арифметико-логическое устройство. Что же касается скорости стандартных операций с плавающей точкой, то она с выходом новых поколений процессоров не меняется. Это и понятно, ведь ставка нынче делается на внедрение в обиход новых наборов инструкций с более высокой разрядностью.

При оценке мультимедийной производительности на первое место выходит скорость выполнения векторных инструкций. Поэтому здесь преимущество Haswell проявляется особенно сильно при использовании набора AVX2. Если же новые инструкции из рассмотрения исключить, то мы увидим лишь 7-процентное увеличение быстродействия по сравнению с Ivy Bridge. Который, в свою очередь, быстрее Sandy Bridge лишь на 1–2 процента.

Похожим образом дело обстоит и со скоростью работы криптографических алгоритмов. Ввод в строй новых поколений структур поднимает производительность лишь на единицы процентов. Весомый прирост скорости можно получить только в том случае, если использовать Haswell и его новые команды. Однако не следует обольщаться: извлечение преимущества из AVX2 в реальной жизни требует переписывания программного кода, а это, как известно, — процесс далеко не быстрый.

Не слишком оптимистично выглядит и то, что произошло с латентностью кеш-памяти.

Таблица 3.

Латентность (задержка), такты

Sandy Bridge

Ivy Bridge

Haswell

L1D-кеш

4

4

4

L2-кеш

12

12

12

L3-кеш

18

19

21

Кеш третьего уровня в Haswell действительно работает с большими задержками, нежели в процессорах прошлого поколения, так как Uncore-часть этого процессора получила асинхронное тактование относительно вычислительных ядер.

Однако увеличение задержек с лихвой компенсируется двукратным ростом полосы пропускания, произошедшим не только в теории, но и на практике.

Таблица 4.

Пропускная способность, Гбайт/с

Sandy Bridge

Ivy Bridge

Haswell

L1D-кеш

510,68

507,64

980,79

L2-кеш

377,37

381,63

596,7

L3-кеш

188,5

193,38

206,12

Но в целом структура Haswell на фоне Sandy Bridge всё-таки не выглядит заметным продвижением вперёд. Принципиальное преимущество наблюдается лишь при задействовании набора команд AVX2, и наблюдать его пока можно лишь в синтетических тестах, так как реальное программное обеспечение должно ещё пройти по длительному пути оптимизации и адаптации. Если же новые инструкции в рассмотрение не брать, то средний уровень превосходства Haswell над Sandy Bridge составляет порядка 10 процентов. И такой разрыв процессора с более старой структурой  Sandy Bridge вполне по силам преодолеть за счёт разгона. Особенно если учесть тот факт, что частотный потенциал старых процессоров выше, чем у их современных последователей.

О многоядерности процессоров

 

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

Кризис жанра

Тот фантастический темп, в котором идет развитие всей микроэлектронной промышленности и IT-отрасли последние годы, был предсказан почти полвека назад, в  1965 году (всего лишь через шесть лет после изобретения интегральной микросхемы) Гордоном Муром и всем хорошо известен как эмпирический закон имени его самого.  Мур предсказал, что число транзисторов в одном кристалле будет удваиваться каждые два года. И вот тут хотелось бы отметить один интересный нюанс. Применительно к «обычным процессорам»  простой рост числа транзисторов напрямую никак не сказывается на его производительности. Куда более значимым параметром выступает частота, на которой эти транзисторы работают. Если  посмотреть на историю развития процессоров с архитектурой x86, то можно увидеть как рост числа транзисторов сказывался на общей производительности, чаще всего косвенным образом.

Подходы к разработке процессоров, впервые примененные в процессоре Intel i386DX, оставались актуальными более 20 лет. И только сейчас они потихоньку сменяются новыми. Вспомним несколько вех:

Увеличение разрядности (32-х разрядность в 386-ом, современная 64-х разрядность). Прирост идет за счет того, что на уровне отдельных команд  можно манипулировать большим объемом данных

Усложнение логики исполнения потока команд, спекулятивное исполнение, появление множества однородных исполнительных устройств. Суть всех этих нововведений позволяет процессору в линейном потоке команд выполнять одновременно несколько идущих друг за другом команд.

Появление наборов новых команд, от MMX до SSE и AVX всех версий. Суть очень похожа на рост разрядности: команды из этих расширений умеют манипулировать данными большой разрядности (корректнее сказать, это операции над массивами данных).

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

Рост объемов кеш-памяти. Обеспечивает снижение числа обращений в медленную внешнюю память.

И наконец многоядерность.

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

Рост эффективности исполнения команд процессорным ядром — это весьма и весьма небыстрый процесс (и 5% прироста на мегагерц при смене поколения — это очень хорошая цифра). Поэтому долгие годы, до наступления кризиса в этой сфере и прихода эры многоядерности, рост производительности шел в основном за счет тактовой частоты. Тут все просто и понятно: заставил процессор, даже без всяких нововведений в области его структуры, работать на более высокой тактовой частоте — получил пропорциональный рост производительности. Причем, заметьте, даже для старых приложений.

Набор команд Streaming SIMD Extensions (SSE), появившись в процессоре Pentium III образца 1999 года, тоже вызывал немало вопросов по поводу своей полезности. Сегодня же без применения SSE и его наследников обойтись почти невозможно. О том, что расти старыми темпами вверх по частоте до бесконечности не получится, в законодателе мод, фирме Intel, задумывались еще в эпоху первого поколения процессоров Pentium. И понятно, что если не получается расти в высоту, то единственный способ роста — в ширину. Примерно в то время появился упомянутый выше набор команд для работы с массивами данных MMX. И именно в те годы в недрах фирмы начали разрабатывать  процессор с принципиально новой структурой — были начаты работы по   семейству процессоров Itanium, которое будет управляться «широкими» инструкциями с так называемым явным параллелизмом (EPIC). Более того, перспективы роста в рамках x86-архитектуры в те годы казались настолько туманными, что на архитектуру Itanium предполагалось пересадить всю индустрию ПК (именно поэтому эти процессоры умели эмулировать x86 набор команд — планировался долгий «переходный период»).

Рост по частоте — это самый простой и заманчивый способ обеспечить прирост производительности процессоров. В конце 90-х инженеры фирмы Intel придумали структуру NetBurst, и тогда некоторым из них показалось, что кто-то Большой надежно схвачен за бороду. Фирма а Intel прогнозировала к 2010 году процессоры с частотой в 10 ГГц в практически каждом отдельно взятом ПК.

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

Структура процессоров Core 2ознаменовала собой начало новой эры — эры роста процессоров не в высоту, а в ширину.

Производительность процессора

На уровне интуиции с понятием производительности процессора проблем не возникает. Чем быстрее процессор выполняет программу, тем он более производителен. В качестве примера можно рассмотреть процесс конвертирования аудиофайла в формат MP3. Из двух процессоров более производительным  считается тот, который быстрее выполняет конвертирование. Другой пример — финальный рендеринг сцены, созданной в какой-либо программе по трехмерному моделированию (например, 3ds max или Maya). Чем быстрее процессор справится с задачей рендеринга, тем он более производителен. Таких примеров можно привести достаточно много, но и без того понятно, что производительность процессора связана со скоростью выполнения им программного кода. Собственно, именно таким образом и трактуется производительность процессора (Performance), под которой понимают скорость выполнение им команд программного кода (Instruction Per Second, IPS) или количество команд, выполняемых в единицу времени (за одну секунду). Если попытаться записать данное определение в виде математической формулы, то получится следующее:

Как известно, процессор работает на определенной тактовой частоте, которая является одной из его важнейших технических характеристик. За каждый такт, то есть промежуток времени, обратный тактовой частоте, процессор выполняет определенное количество команд. Поэтому вместо количества команд программы, выполняемых за единицу времени, удобнее рассматривать количество команд программы, выполняемых за один такт процессора (Instruction Per Clock, IPC). IPC зависит и от структуры процессора, и от технологии производства, определяющей минимальные размеры используемых транзисторов и их быстродействие, и от оптимизации программного кода к структуре процессора.

Переписав выражение для производительности процессора в виде произведения количества команд, выполняемых за один такт процессора, на количество тактов процессора за единицу времени (тактовая частота процессора, F), получим:

Как видим, производительность процессора прямо пропорциональна как тактовой частоте, так и количеству команд, выполняемых за один такт. Из этой формулы также следует, что существует два принципиально разных подхода к увеличению производительности процессора. Первый из них заключается в увеличении тактовой частоты, а второй — в увеличении IPC.

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

Из истории развития  процессоров фирмы Intel понятно, что до некоторого  времени доминирующим средством увеличения производительности процессора являлось увеличение  тактовой частоты. Производительность процессоров буквально отождествлялась с их тактовой частотой, а структура создавалась именно с расчетом обеспечения ее максимально возможного увеличения. Примером этого может служить структура  NetBurst, положенная в основу процессоров семейства Pentium 4, особенностью которой является супердлинный конвейер, что позволяло наращивать тактовую частоту. Дабы не рассматривать структуру  NetBurst детально, поясним это на ассоциативном примере. Предположим, что необходимо собрать несколько ПК, что может выполнить один человек, затратив определенное время. Однако эту же работу можно поручить нескольким людям, организовав их труд по схеме конвейера, когда каждый из них выполняет определенную операцию на конвейере, а собираемые системные блоки движутся по ленте транспортера от одного сборщика к другому. Понятно, что чем больше человек занято на конвейере (число ступеней конвейера), тем меньший объем работы выполняет каждый из них, а следовательно, тем быстрее сможет двигаться конвейер.

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

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

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

Если вспомнить  ассоциативный пример с конвейерной сборкой ПК, становится понятно, что чем больше ступеней у конвейера, тем меньше работы выполняется на каждой ступени и, следовательно, тем меньше времени требуется для прохождения командой данной ступени. А поскольку каждая ступень выполняется за один такт, длинные конвейеры позволяют повышать тактовую частоту процессора, что невозможно в случае коротких конвейеров. Из этого следует, что длина конвейера тесно связана с максимальной тактовой частотой, на которой может работать процессор. В то же время длина конвейера является одним из параметров, определяющих IPC, — чем больше ступеней в конвейере (при прочих равных условиях), тем меньше команд выполняется процессором на каждом такте. Таким образом, мы приходим к еще одному важному выводу: длина конвейера связана и с тактовой частотой процессора, и с IPC, следовательно, максимальная тактовая частота связана с IPC, причем чем выше IPC, тем ниже максимально возможная тактовая частота и наоборот.

Всякий процессор в конечном счете должен быть сконструирован таким образом, чтобы за минимальное время выполнять максимальное количество команд. Ведь именно скорость выполнения процессором команд и определяет его производительность.

Негативные последствия увеличения частоты процессора

Структура  NetBurst, положенная в основу процессоров семейства Pentium 4, изначально разрабатывалась под возможность наращивания тактовой частоты. Первоначально (в процессорах на ядре с кодовым названием Northwood) длина конвейера составляла 20 ступеней, а впоследствии (в процессорах на ядре с кодовым названием Prescott) она была увеличена до 31 ступени. В результате за пять лет существования процессоров семейства Pentium 4 их тактовая частота была увеличена более чем в три раза. Стартовав с отметки чуть больше 1 ГГц, за пять лет она достигла 3,8 ГГц.

Казалось бы, если увеличение  тактовой частоты представляет собой довольно эффективное средство для увеличения производительности процессоров, что мешает и дальше двигаться в этом же направлении? Почему можно утверждать, что наращивание тактовой частоты процессоров как доминирующий способ увеличения производительности — это тупик?

Дело в том, что увеличение тактовой частоты процессора приводит к росту его энергопотребления и, как следствие, к повышению тепловыделения.

Зависимость потребляемой процессором мощности от его тактовой частоты можно представить следующей формулой

 

Power = CU2F.

 

То есть мощность, потребляемая процессором, прямо пропорциональна тактовой частоте (F), квадрату напряжения питания процессора (U2) и его так называемой динамической емкости (C). Учитывая, что сама тактовая частота обусловлена напряжением питания процессора, потребляемая мощность нелинейным образом зависит от частоты процессора. Соответственно получаем нелинейную связь между производительностью процессора и потребляемой им мощностью.

Эмпирическим путем установлено, что при увеличении тактовой частоты на 20% производительность процессора возрастает на 13%. Дело в том, что, несмотря на теоретическую прямолинейную зависимость между производительностью процессора и его тактовой частотой, в реальности она не является строго пропорциональной. При этом потребляемая процессором мощность возрастает на 73%! При уменьшении тактовой частоты процессора на 20% производительность уменьшается на 13%, а потребляемая мощность — на 49%! Этот пример наглядно демонстрирует, что увеличение тактовой частоты приводит к явному дисбалансу между приростом производительности и потребляемой мощностью.

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

Что же делать? К счастью, на помощь приходит как раз пресловутая возможность совершенствовать техпроцесс. Это значит, что при той же тактовой частоте и потребляемой мощности можно делать процессоры с большим количеством транзисторов. Возникает резонный вопрос — как лучше использовать эти «лишние» транзисторы? Хорошая новость заключается в том, что значительное количество «бесплатных» транзисторов попадают в те блоки процессора, которые не связаны напрямую с «многоядерностью», как например блоки SSE/AVX, а также в кеш-память различных уровней. Это дает возможность повышать производительность процессора на десятки процентов от модели к модели при том же количестве основных вычислительных ядер.

Таким образом, запаса «последовательной» производительности хватит еще надолго. Кроме того, как подсказывает практика, целый класс алгоритмов так и будет существовать только в том или ином последовательном виде.

В погоне за производительностью, которая, как уже отмечалось, в семействе  Pentium 4 обеспечивалась главным образом увеличением тактовой частоты, последние версии процессоров со структурой NetBurst достигли уровня энергопотребления в 130 Вт. Казалось бы, ничего страшного — ведь это соответствует одной-двум лампам накаливания и любая люстра в квартире потребляет больше электроэнергии. Однако проблема заключается в том, что эта мощность выделяется процессором в виде тепла, что приводит к его нагреванию. И если для лампы накаливания такой нагрев не критичен, то для процессора все не так просто. Процессоры настольных ПК могут сохранять нормальную работоспособность вплоть до температуры 70 °С, а это означает, что при столь высоком энергопотреблении необходимо обеспечить эффективный отвод тепла, для чего используются процессорные кулеры. Проблема, однако, заключается в том, что современные воздушные процессорные кулеры обеспечивают эффективное охлаждение процессоров при энергопотреблении только до 100 Вт — лишь немногие мощные устройства позволяют охлаждать процессоры с более высоким энергопотреблением, причем эти кулеры довольно шумные.

С учетом того, что энергопотребление десктопных процессоров семейства Pentium 4 уже достигло своего критического значения, дальнейший рост их производительности просто был невозможен в рамках существующей структуры. Можно говорить, что структура NetBurst полностью исчерпала свои потенциальные возможности и создала своего рода тупиковую ситуацию в дальнейшем развитии процессоров.

Интересно отметить, что нелинейная зависимость между потребляемой мощностью и производительностью процессора была впервые подмечена Фредом Поллаком (Fred Pollack) в 1999 году, еще до внедрения структуры NetBurst. Остается лишь спросить у фирмы Intel — если все с самого начала было известно, то зачем вообще понадобилось разрабатывать структуру NetBurst, у которой не было будущего? Скорее всего, ответ на этот вопрос достаточно прост: восемь лет назад, когда проблема энергопотребления процессоров не стояла столь остро, проще было убедить всех в том, что будущее за тактовой частотой, а не заниматься разработкой новой структуры. Помните маркетинговые заявления, что недалек тот день, когда тактовая частота процессоров будет измеряться десятками гигагерц? Мечты остались мечтами, а то, что должно было случиться, случилось. Сейчас о тактовой частоте процессоров как о средстве увеличения производительности уже не говорят.

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

Энергетическая эффективность процессора

Если абсолютную производительность процессора принято измерять в количестве программных команд, выполняемых в единицу времени (Instruction Per Second, IPS), то энергетическую эффективность процессоров можно характеризовать величиной, численно равной среднему количеству поглощенной энергии, приходящейся на одну выполненную команду (Energy Per Instruction, EPI). EPI измеряется в джоулях (Дж) и определяется по следующей формуле:

 

EPI нетрудно связать и с другой часто используемой характеристикой энергетической эффективности процессора, иногда называемой оптимизированной производительностью процессора и определяемой как производительность процессора в расчете на каждый ватт потребляемой мощности (Performance Per Watt):

 

Соответственно:

 

EPI = Power / Performance.

Таким образом, энергетическую эффективность процессора EPI можно трактовать как потребляемую мощность в расчете на единицу производительности, если последняя измеряется в количестве команд, исполняемых за единицу времени.

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

Энергетическая эффективность процессоров зависит от таких факторов, как структура процессора, технологический процесс производства и напряжение питания.

Возвращаясь к семейству процессоров  Pentium 4, отметим, что их структура была изначально ориентирована на достижение максимальной производительности любыми путями. Речь идет о высокой динамической емкости  процессоров, за счет чего они потребляют достаточно много энергии для обработки каждой команды. Длинный конвейер, сложная структура блока внеочередного исполнения команд, спекулятивный характер обработки команд и многое другое — все это в конечном счете ведет к повышению значении EPI. Итак, к особенностям структуры  NetBurst можно отнести не только возможность увеличения производительности за счет увеличения тактовой частоты, но и высокое значение EPI.

Пользователю хотелось бы иметь процессор, который, с одной стороны, был бы высокопроизводительным, а с другой — обладал бы низким значением EPI, то есть был бы энергоэффективным. Одновременно удовлетворить эти требования могут многоядерные процессоры и процессоры на основе принципиально новой структуры, которая позволяла бы реализовать рост производительности за счет не увеличения тактовой частоты, а увеличения количества команд, выполняемых процессором за один такт (IPC).

Преимущества многоядерной структуры процессора

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

В реальности, конечно, все несколько сложнее — результат будет зависеть от используемого приложения и его оптимизации к двухъядерному процессору. То есть, чтобы приложение могло одновременно задействовать несколько процессорных ядер, оно должно хорошо распараллеливаться. Если же программа написана таким образом, что подразумевает только последовательное выполнение команд, от многоядерности проку не будет.

Для того чтобы продемонстрировать, как именно увеличивается  производительность многоядерного процессора в зависимости от оптимизации программы к многоядерной структуре, рассмотрим следующий пример.

Имеется многоядерный процессор с количеством ядер равным n. Предположим, что на этом процессоре выполняется программа, включающая N команд, причем S команд этой программы может выполняться только последовательно друг за другом, а P (равное N – S) команд являются программно независимыми друг от друга и могут выполняться одновременно на всех ядрах процессора. Обозначим через (равное S / N) — долю команд, выполняемых последовательно, а через(равное 1 – s) — долю команд, выполняемых параллельно.

 

Рис. 1. Выполнение программы на одноядерном процессоре.

В случае применения одноядерного процессора (рис. 1) время, затрачиваемое на выполнение всей программы, составит:

 

t1 = N / IPS.

 

В случае использования n-ядерного процессора (рис. 2) время, затрачиваемое на выполнение всего программного кода, окажется меньше за счет параллельного выполнения P команд на n ядрах процессора и составит:

 Рис. 2. Выполнение программного кода на многоядерном процессоре

Поскольку приростом производительности в данном случае можно считать сокращение времени выполнения программы при использовании многоядерного процессора по сравнению со временем выполнения той же программы при применении одноядерного процессора, то есть t1 / tn, получим, что прирост производительности составит:

 

Графическая зависимость прироста производительности от числа ядер процессора показана на рис. 3.

 

Рис. 3. Зависимость прироста производительности от числа ядер процессора

Как видно из приведенной формулы, прирост производительности в случае многоядерной структуры процессора в большой степени зависит от оптимизации приложения к многоядерной структуре, то есть от его способности распараллеливаться. К примеру, даже в случае, когда 90% команд программы распараллеливается на несколько исполнительных ядер, использование четырехъядерного процессора позволяет получить только трехкратный прирост производительности в сравнении с одноядерной структурой процессора.

Рассмотренный  пример представляет собой идеальную ситуацию, но в реальности все несколько сложнее, тем не менее основная идея остается неизменной: использование многоядерных процессоров требует внесения кардинальных изменений в программное обеспечение. Нужно отметить, что далеко не все приложения даже сегодня оптимизированы под многоядерную структуру процессоров. К примеру, многие игры пока еще не могут получать ощутимого прироста от многоядерной структуры. В то же время имеется ряд приложений, которые, наоборот, позволяют получить ощутимый прирост производительности от многоядерности. К ним относятся программы финального рендеринга трехмерных сцен, программы для работы с видеомонтажем и обработки звука и многие другие. Отметим, что все новые версии популярных программ оптимизируются под многоядерную структуру процессоров, поскольку за ними будущее.

До сих пор, обсуждая прирост производительности, который можно получить при переходе от одноядерной к многоядерной структуре, было рассмотрено только одно приложение. Тем не менее многоядерные процессоры позволяют ощутить существенный прирост производительности при одновременной работе нескольких приложений. В идеальном случае каждое приложение может исполняться на отдельном ядре процессора независимо от других приложений. К примеру, можно параллельно конвертировать видеофайлы, играть в игры и т.п.

Подводя итог, еще раз подчеркнем, что многоядерная структура процессоров позволяет одновременно решать две глобальные задачи: увеличивать производительность процессоров и одновременно создавать энергоэффективные процессоры.

Конечно, многоядерная структура — это лишь один из рецептов создания высокопроизводительных энергоэффективных процессоров. Для создания действительно энергоэффективного многоядерного процессора необходимо, чтобы каждое его ядро было оптимизировано для многоядерной структуры и к тому же было энергоэффективным.

Эволюция вычислительной мощи от центральных процессоров к графическим процессорам

Хотя в 2000 г. фирма  Intel прогнозировала частоту процессоров 10 ГГц,  к 2011 г. реальность оказалась совершенно другой. Главная вычислительная мощь оказалась не у центральных процессоров (CPU), а у графических процессоров (GPU). На рис. 4 приведен график роста количества операций с плавающей запятой (FLOPs) у CPU и GPU за 2002 – 2011 гг.


Рис. 4. График  роста количества операций с плавающей запятой (FLOPs) у CPU и GPU за 2002 – 2011 гг.

На рис. 5 приведен тот же график, но в  на логарифмическом масштабе.



Рис. 5. График  роста количества операций с плавающей запятой (FLOPs) у CPU и GPU за 2002 – 2011 гг. влогарифмическом масштабе.

Понятно, что за счёт узкой специализации графический процессор может практически всю свою производительность отдавать на арифметические операции, тогда как архитектура CPU гораздо сложнее.

В настоящее время тактовая частота процессоров Intel не превышает 4,5  ГГц.
Правда, общая производительность чипов продолжает расти за счёт увеличения числа ядер. На рис. 6 приведен график роста производительности центральных  процессоров (CPU) и графических процессоров (GPU) в области вычислений с плавающей точкой за 2002 – 2011 гг.

Параллельная по своей сути природа построения 3D-изображений (а также относительная простота используемых при этом алгоритмов) позволила GPU уйти в такой отрыв, что современным процессорам общего назначения остается только, раскрыв рот, смотреть на эту стремительно растущую кривую. С такой же эффективностью использовать дополнительные транзисторы, которые из года в год индустрии дарит пока еще работающий закон Мура, разработчики CPU, увы, не могут.


Рис. 6. График роста производительности центральных  процессоров (CPU) и графических процессоров (GPU) в области вычислений с плавающей точкой за 2002 – 2011 гг.

Оперативная память

 Определения

Аббревиатура SDRAM расшифровывается как Synchronous Dynamic Random Access Memory — синхронная динамическая память с произвольным доступом.

Под «синхронной» операцией SDRAM в настоящее время следует понимать строгую привязку временных интервалов отправки команд и данных по соответствующим интерфейсам устройства оперативной памяти к определенным синхросигналам, но не по произвольным временным интервалам (как это осуществлялось в асинхронной DRAM).  Проще говоря, все операции в ОЗУ совершаются строго по фронту/срезу синхросигнала интерфейса памяти.

Понятие «динамической» памяти, DRAM, относится ко всем типам оперативной памяти, начиная с самой древней, «обычной» асинхронной динамической памяти и заканчивая современной DDR3. Этот термин вводится в противоположность понятия «статической» памяти (SRAM) и означает, что содержимое каждой ячейки памяти периодически необходимо обновлять (ввиду особенности ее конструкции, продиктованной экономическими соображениями). В то же время, статическая память, характеризующаяся более сложной и более дорогой конструкцией ячейки и применяемая в качестве кэш-памяти в процессорах, свободна от циклов регенерации, т.к. в ее основе лежит не емкость (динамическая составляющая), а триггер (статическая составляющая).

Наконец, стоит также упомянуть о «памяти с произвольным доступом» — Random Access Memory, RAM. Традиционно, это понятие противопоставляется устройствам «памяти только на чтение» — Read-Only Memory, ROM. Тем не менее, противопоставление это не совсем верно, т.к. из него можно сделать вывод, что память типа ROM не является памятью с произвольным доступом. Это неверно, потому как доступ к устройствам ROM может осуществляться в произвольном, а не строго последовательном порядке. И на самом деле, наименование «RAM» изначально противопоставлялось ранним типам памяти, в которых операции чтения/записи могли осуществляться только в последовательном порядке. В связи с этим, более правильно назначение и принцип работы оперативной памяти отражает аббревиатура «RWM» (Read-Write Memory), которая, тем не менее, встречается намного реже. Заметим, что русскоязычным сокращениям RAM и ROM — ОЗУ (оперативное запоминающее устройство) и ПЗУ (постоянное запоминающее устройство), соответственно, подобная путаница не присуща.

Как работает динамическая память (DRAM)

Носителем информации в динамической памяти является электрическая ёмкость или конденсатор. Ячейки памяти (рис. 1 и рис. 2 ), в основе которых лежит конденсатор, объединяются в массив (рис. 3 ).

Рис. 1.

Рис. 2 Устройство ячейки динамической памяти.

Рис. 3.

На физическом уровне ячейки объединяются в прямоугольную матрицу, горизонтальные линейки которой называются строками (ROW), а вертикальные - столбцами (Column) или страницами (Page).

Рис. 4.

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

Чувствительный усилитель (sense amp), подключенный к каждому из столбцов матрицы, реагируя на слабый поток электронов, устремившихся через открытые транзисторы с обкладок конденсаторов, считывает всю страницу целиком.  Именно страница является минимальной порцией обмена с ядром динамической памяти. Чтение/запись отдельно взятой ячейки невозможно! Действительно, открытие одной строки приводит к открытию всех, подключенных к ней транзисторов, а, следовательно, - разряду закрепленных за этими транзисторами конденсаторов.

Чтение ячейки разрушительно  по своей природе, поскольку sense amp (чувствительный усилитель) разряжает конденсатор в процессе считывания его заряда. "Благодаря" этому динамическая память представляет собой память разового действия. Разумеется, такое положение дел никого устроить не может, и потому во избежание потери информации считанную строку приходится тут же перезаписывать вновь.

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

Ячейка памяти может хранить только один бит информации. Чтобы хранить один байт, используется 8 элементарных ячеек памяти. При этом они адресуются одинаково и организованы с использованием шины данных шириной в 8 линий. Такие объединённые ячейки образуют слово. Обычно микросхемы памяти имеют размер слова 4, 8, 16 бит. Ширина шины данных при этом равна 4, 8, 16 линий (или разрядность 4, 8. 16 бит). Простой модуль памяти DIMM имеет ширину шины данных 64 линий.

Логическая организация микросхемы памяти

Как уже было сказано выше, микросхема DRAM, фактически, представляет собой двумерный массив (матрицу) элементов, состоящих из одного или нескольких элементарных физических ячеек. Очевидно, что главной характеристикой этого массива является его емкость, выражаемая в количестве бит информации, которую он способен вместить. Например, «1-Гбит», «4-Гбит» микросхемы памяти — речь здесь идет именно об этом параметре. Однако составить эту емкость можно разными способами — речь  не о количестве строк и столбцов, но о размерности, или «вместимости» индивидуального элемента. Последняя прямо связана с количеством линий данных, т.е. шириной внешней шины данных микросхемы памяти. Ширина шины данных самых первых микросхем памяти составляла всего 1 бит, в настоящее же время наиболее часто встречаются 4-, 8- и 16- (реже — 32-) битные микросхемы памяти. Таким образом, микросхему памяти емкостью 512 Мбит можно составить, например, из 128М (134 217 728) 4-битных элементов, 64М (67 108 864) 8-битных элементов или 32М (33 554 432) 16-битных элементов — соответствующие конфигурации записываются как «128Mx4», «64Mx8» и «32Mx16». Первая из этих цифр именуется глубиной микросхемы памяти (безразмерная величина), вторая — шириной (выраженная в битах).

Существенная отличительная особенность микросхем SDRAM от микросхем более ранних типов DRAM заключается в разбиении массива данных на несколько логических банков (как минимум — 2, обычно — 4). Не следует путать это понятие с понятием «физического банка» (называемого также «ранком» (rank) памяти), определенным для модуля, но не микросхемы памяти — его мы рассмотрим далее. Сейчас лишь отметим, что внешняя шина данных каждого логического банка (в отличие от физического, который составляется из нескольких микросхем памяти для «заполнения» шины данных контроллера памяти) характеризуется той же разрядностью (шириной), что и разрядность (ширина) внешней шины данных микросхемы памяти в целом (x4, x8 или x16). Иными словами, логическое разделение массива микросхемы на банки осуществляется на уровне количества элементов в массиве, но не разрядности элементов. Таким образом, рассмотренные выше реальные примеры логической организации 512-Мбит микросхемы при ее «разбиении» на 4 банка могут быть записаны как 32Mx4x4 банка, 16Mx8x4 банка и 8Mx16x4 банка, соответственно. Тем не менее, намного чаще на маркировке микросхем памяти (либо ее расшифровке в технической документации) встречаются именно конфигурации «полной» емкости, без учета ее разделения на отдельные логические банки, тогда как подробное описание организации микросхемы (количество банков, строк и столбцов, ширину внешней шины данных банка) можно встретить лишь в подробной технической документации на данный вид микросхем SDRAM.

Разбиение массива памяти SDRAM на банки было введено, главным образом, из соображений производительности (точнее, минимизации системных задержек — т.е. задержек поступления данных в систему). В самом простом и пока достаточном изложении, можно сказать, что после осуществления любой операции со строкой памяти, после дезактивации сигнала RAS#, требуется определенное время для осуществления ее «подзарядки». И преимущество «многобанковых» микросхем SDRAM заключается в том, что можно обращаться к строке одного банка, пока строка другого банка находится на «подзарядке». Можно расположить данные в памяти и организовать к ним доступ таким образом, что далее будут запрашиваться данные из второго банка, уже «подзаряженного» и готового к работе. В этот момент вполне естественно «подзаряжать» первый банк, и так далее. Такая схема доступа к памяти называется «доступом с чередованием банков» (Bank Interleave).

Интерфейс микросхемы памяти

Физически микросхема памяти (не путать с модулями памяти) представляет собой прямоугольный кусок керамики (или пластика)  с   множеством ножек.

В первую очередь выделим среди них линии адреса и линии данных (рис. 5).

Рис. 5.

Линии адреса, как и следует из их названия, служат для выбора адреса ячейки памяти, а линии данных - для чтения и для записи ее содержимого. Необходимый режим работы определяется состоянием специального вывода Write Enable (Разрешение Записи).

Низкий уровень сигнала WE готовит микросхему к считыванию состояния линий данных и записи полученной информации в соответствующую ячейку, а высокий, наоборот, заставляет считать содержимое ячейки и выдать его значения в линии данных.

Такое решение  сокращает количество выводов микросхемы, что в свою очередь уменьшает ее габариты. А, чем меньше габариты, тем выше предельно допустимая тактовая частота. Почему?

Во-первых, в силу ограниченной скорости распространения электричества, длины проводников, подведенных к различным ножкам микросхемы, должны не сильно отличаться друг от друга, иначе сигнал от одного вывода будет опережать сигнал от другого.

Во-вторых, длины проводников не должны быть очень велики - в противном случае задержка распространения сигнала "съест" все быстродействие.

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

В-четвертых, всякий проводник обладает электрической емкостью. А емкость и скорость передачи данных - несовместимы! Вот только один пример: "…первый трансатлантический кабель для телеграфа был успешно проложен в 1858 году,… когда напряжение прикладывалось к одному концу кабеля, оно не появлялось немедленно на другом конце и вместо скачкообразного нарастания достигало стабильного значения после некоторого периода времени. Когда снимали напряжение, напряжение приемного конца не падало резко, а медленно снижалось. Кабель вел себя как губка, накапливая электричество. Это свойство  называется емкостью"

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

Столбцы и строки матрицы памяти тем же самым способом совмещаются в единых адресных линиях. В случае квадратной матрицы количество адресных линий сокращается вдвое, но и выбор конкретной ячейки памяти отнимает вдвое больше тактов, ведь номера столбца и строки приходится передавать последовательно. Причем, возникает неоднозначность, что именно в данный момент находится на адресной линии: номер строки или номер столбца? А, быть может, и вовсе не находится ничего? Решение этой проблемы потребовало двух дополнительных выводов, сигнализирующих о наличии столбца или строки на адресных линиях и окрещенных  RAS (от row address strobe - строб адреса строки) и CAS (от column address strobe - строб адреса столбца) соответственно. В спокойном состоянии на обоих выводах поддерживается высокий уровень сигнала, что говорит микросхеме: никакой информации на адресных линиях нет и никаких действий предпринимать не требуется.

При считывании информации происходят следующие операции.

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

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

На финальной стадии цикла обмена контроллер считывает состояние линий данных, дезактивирует сигналы RAS и CAS, устанавливая их в высокое состояние.

Так как при чтении заряд ёмкостей ячеек памяти теряется, то производится подзарядка этих ёмкостей или закрытие строки (по-английски Precharge). После закрытия строки дальнейшее считывание данных невозможно без повторной активации.

Задержка между подачей номера строки и номера столбца на техническом жаргоне называется "RAS to CAS delay" (tRCD). Задержка между подачей номера столбца и получением содержимого ячейки на выходе - "CAS delay" (tCAC), а задержка между чтением последней ячейки и подачей номера новой строки - "RAS precharge" (tRP).

При записи данных всё происходит точно так же, только чтение меняется на запись и при закрытии строки происходит непосредственная запись в массив памяти.

Со временем конденсаторы ячеек разражаются и их необходимо подзаряжать. Операция подзарядки называется регенерацией (по-английски Refresh) и выполняется каждые 64 мс для каждой строки массива памяти.

Банки памяти

Чтобы обеспечить возможность быстрой работы одновременно с разными участками памяти используется структура  с несколькими массивами памяти или банками (по-английски Bank). Банки памяти работают полностью независимо. Например, данные можно считывать из памяти банка 1, обрабатывать и записывать в память банка 2. При этом будут отсутствовать задержки на активацию и закрытие строк данных в массиве памяти, что было бы в случае одного банка.

Возможна различная организация использования банков. При этом по-разному выполняется трансляция адреса памяти, который использует процессор, в последовательность: номер банка, номер строки массива памяти, номер колонки массива памяти. В простейшем случае банки памяти идут последовательно. Соответственно преимущества от наличия нескольких банков будут, только если обращения к памяти сильно разнесены в адресном пространстве. Обычно программы работают с небольшим локальным участком памяти и не будут иметь ускорения. Возможна организация с чередованием банков (по-английски Interleaving). Сначала идёт строка первого банка, потом второго, потом опять первого, и так далее до конца памяти. Вероятность, что будут использоваться участки памяти, принадлежащие разным банкам, значительно увеличивается. Но всегда возможны "неудобные" случаи, когда рабочие участки памяти разбросаны так, что принадлежат одному банку. Тем не менее, наличие нескольких банков повышает производительность. Чем больше банков, тем лучше.

Рис. 6.

Различия между  памятями SDR,  DDR, DDR2 , DDR3

По большей части микросхемы DDR, DDR2, DDR3  похожи на микросхемы SDR  так, все типы микросхем, как правило, имеют одинаковую логическую организацию (при одинаковой емкости), включая 4-банковую организацию массива памяти, и одинаковый командно-адресный интерфейс. Фундаментальные различия между SDR и DDR, DDR2, DDR3   лежат в организации логического слоя интерфейса данных.

По интерфейсу данных памяти типа SDR  данные передаются только по положительному перепаду («фронту») синхросигнала. При этом внутренняя частота функционирования микросхем  совпадает с частотой внешней шины данных, а ширина внутренней шины данных SDR  (от непосредственно ячеек до буферов ввода-вывода) совпадает с шириной внешней шины данных. В то же время, по интерфейсу данных памяти типа:

DDR - данные передаются дважды за один такт шины данных — как по положительному перепаду синхросигнала («фронту»), так и по отрицательному («срезу»);

DDR2 - данные передаются четыре раза за один такт шины данных;

DDR3 - данные передаются восемь раз за один такт шины данных.

Возникает вопрос — как можно организовать удвоенную скорость передачи данных по отношению к частоте шины памяти? Напрашиваются два решения — можно либо увеличить в 2 раза внутреннюю частоту функционирования микросхем памяти (по сравнению с частотой внешней шины), либо увеличить в 2 раза внутреннюю ширину шины данных (по сравнению с шириной внешней шины). Достаточно наивно было бы полагать, что в реализации стандарта DDR было применено первое решение, но и ошибиться в эту сторону довольно легко, учитывая «чисто маркетинговый» подход к маркировке модулей памяти типа DDR, якобы функционирующих на удвоенной частоте (так, модули памяти DDR с реальной частотой шины 200 МГц именуются «DDR-400»). Тем не менее, гораздо более простым и эффективным — исходя как из технологических, так и экономических соображений — является второе решение, которое и применяется в устройствах типа DDR . Такая структура, применяемая в DDR , называется структурой «2n-предвыборки» (2n-prefetch). В этой структуре доступ к данным осуществляется «попарно» — каждая одиночная команда чтения данных приводит к отправке по внешней шине данных двух элементов (разрядность которых, как и в SDR , равна разрядности внешней шины данных). Аналогично, каждая команда записи данных ожидает поступления двух элементов по внешней шине данных. Именно это обстоятельство объясняет, почему величина «длины пакета» (Burst Length, BL) при передаче данных в устройствах DDR  не может быть меньше 2.

Устройства типа DDR2  являются логическим продолжением развития структуры «2n-prefetch», применяемой в устройствах DDR . Вполне естественно ожидать, что структура устройств DDR2  именуется «4n-prefetch» и подразумевает, что ширина внутренней шины данных оказывается уже не в два, а в четыре раза больше по сравнению с шириной внешней шины данных. Однако речь здесь идет не о дальнейшем увеличении количества единиц данных, передаваемых за такт внешней шины данных — иначе такие устройства уже не именовались бы устройствами «Double Data Rate 2-го поколения». Вместо этого, дальнейшее «уширение» внутренней шины данных позволяет снизить внутреннюю частоту функционирования микросхем DDR2  в два раза по сравнению с частотой функционирования микросхем DDR , обладающих равной теоретической пропускной способностью. С одной стороны, снижение внутренней частоты функционирования микросхем, наряду со снижением номинального питающего напряжения, например,  с 2.5 до 1.8 V, позволяет ощутимо снизить мощность, потребляемую устройствами памяти. С другой стороны, структура 4n-prefetch микросхем DDR2 позволяет достичь вдвое большую частоту внешней шины данных по сравнению с частотой внешней шины данных микросхем DDR — при равной внутренней частоте функционирования самих микросхем.

Поскольку DDR2 — это «все та же DDR»,  по-прежнему имеем удвоенную скорость передачи данных за один такт внешней шины данных — иными словами, на каждом такте внешней шины данных  ожидаем получить не менее двух элементов данных (как всегда, разрядностью, равной разрядности внешней шины данных) при чтении, и обязаны предоставить микросхеме не менее двух элементов данных при записи. В то же время, вспоминаем, что внутренняя частота функционирования микросхем DDR2 составляет половину от частоты ее внешнего интерфейса. Таким образом, на один «внутренний» такт микросхемы памяти приходится два «внешних» такта, на каждый из которых, в свою очередь, приходится считывание/запись двух элементов. Следовательно, на каждый «внутренний» такт микросхемы памяти приходится считывание/запись сразу четырех элементов данных (отсюда и название — 4n-prefetch), т.е. все операции внутри микросхемы памяти осуществляются на уровне «4-элементных» блоков данных. Отсюда получаем, что минимальная величина длины пакета (BL) должна равняться 4. Можно доказать, что, в общем случае, структуре «2nn-prefetch» всегда соответствует минимальная величина Burst Length, равная 2n (n = 1 соответствует DDR; n = 2 — DDR2;  n = 3 —  DDR3).

Различия между оперативными памятями стандартов  SDR, DDR, DDR2 приведены на рис. 7.


Рис. 7. Различия между оперативными памятями стандартов  
SDR, DDR, DDR2.

Память DDR3

Память DDR3 по своему строению и принципам работы не сильно отличается от DDR-памяти предыдущих поколений.

Основная идея, позволившая нарастить частоты DDR3-памяти по сравнению с DDR2, заключается в удвоении размера выборки данных, выполняемой непосредственно из устройств хранения информации в буфера ввода-вывода. В то время как в памяти DDR2  используется 4-битная выборка, в памяти DDR3  применяется выборка размером 8 бит (называемая также 8n-prefetch). Иными словами, технология памяти DDR3  подразумевает двукратное увеличение ширины внутренней шины, соединяющей собственно устройства хранения данных и буфера ввода вывода. В результате, увеличение эффективной частоты передачи данных, происходящее с вводом памяти DDR3, не требует ускорения работы ядра памяти. Возрастает лишь скорость работы внешних буферов. Частота же ядра микросхем памяти оказывается в 8 раз меньше частоты внешней шины и буферов памяти DDR3 (в памяти DDR2 эта частота была в 4 раза меньше частоты внешней шины).

Таким образом, достижение памятью DDR3  более высоких эффективных частот по сравнению с памятью DDR2 становится возможно практически сразу, без внесения каких-либо изменений и усовершенствований в полупроводниковый технологический процесс. Впрочем, применение описанной техники имеет и оборотную сторону – вполне очевидным образом возрастает не только пропускная способность памяти, но и, к сожалению, её латентность.

Вв спецификации памяти DDR3  определяет несколько версий с различными частотами, например,  от 800 до 1600 МГц. В таблице 1 ниже  приведено описание основных параметров перечисленных в спецификации вариантов.


                                Таблица 1.


Если учесть, что латентность памяти DDR2-800 с таймингами 4-4-4 составляет 10 нс, то эффективность памяти DDR3  действительно можно поставить под вопрос. Получается, что эта память способна выигрывать у предшественницы исключительно за счёт увеличения пропускной способности, которая должна компенсировать ухудшающуюся латентность.

Среди плюсов памяти DDR3  в первую очередь следует отметить снизившееся напряжение питания модулей DDR3, достигшее 1.5 В. Это на 20% ниже напряжения памяти DDR2 , что в конечном итоге вылилось в примерно 30-процентное падение энергопотребления при сравнении с DDR2-памятью, работающей на аналогичной тактовой частоте. Этот эффект достигнут благодаря внедрению производителями микросхем памяти более современных технологических процессов. Относительное энергопотребление микросхем памяти DDR2 и DDR3 приведено на рис. 8.


Рис.  8. Относительное энергопотребление микросхем памяти DDR2 и DDR3.

Также, изменению подвергнута была BGA упаковка микросхем в сторону увеличения  контактов. Это дало возможность производителям модулей упростить монтаж и усилить механическую прочность продуктов, а также улучшить качество сигналов при высокой частоте.

Некоторые изменения претерпел и сигнальный протокол DDR3, усовершенствованный в связи с очередным и значительным ростом частоты шины памяти. Для передачи адресов и команд, а также управляющих и стробирующих команд используется fly-by структура с терминированием сигналов непосредственно на модуле. Это значит, что сигналы подаются на все микросхемы модуля не одновременно, а последовательно.


Рис. 9.

Соответственно, изменилась и тактика чтения/записи данных. Контроллер памяти DDR3 должен успешно распознавать и обрабатывать временные смещения при поступлении данных с микросхем, вызванные применением fly-by структуры передачи команд.


                                  Таблица 2.


На рис. 10 приведены диаграммы, отражающие динамику  внедрения памятей различных стандартов.



Рис. 10.

Прогнозировалось, что:

срок жизни памяти DDR3 в высокопроизводительных компьютерах составит немногим более трёх лет, то есть примерно столько же, сколько просуществовала DDR2- память;

память DDR4 начнет внедряться начиная с 2012 года;

полномасштабный переход с памяти DDR3 на память DDR4 произойдет в 2015 году.

Однако, эти прогнозы не оправдались.

Организация модулей  памяти

Основные параметры логической организации микросхем памяти — емкость, глубину и ширину, можно распространить и на модули памяти. Понятие емкости (или объема) модуля очевидно — это максимальный объем информации, который данный модуль способен в себя вместить. Теоретически он может выражаться и в битах, однако общепринятой «потребительской» характеристикой модуля памяти является его объем (емкость), выраженный в байтах — точнее, учитывая современный уровень используемых объемов памяти — в гигабайтах.

Ширина модуля — это разрядность его интерфейса шины данных, которая соответствует разрядности шины данных контроллера памяти и для всех современных типов контроллеров памяти  (SDR, DDR, DDR2, DDR3) составляет 64 бита.  Каким же образом достигается соответствие между 64-битной шириной шины данных контроллера памяти (64-битным интерфейсом модуля памяти), когда типичная ширина внешней шины данных микросхем памяти обычно составляет всего 4, 8 или 16 бит? Ответ очень прост — интерфейс шины данных модуля составляется простым последовательным «слиянием» внешних шин данных индивидуальных микросхем модуля памяти. Такое «заполнение» шины данных контроллера памяти принято называть составлением физического банка памяти. Таким образом, для составления одного физического банка 64-разрядного модуля памяти  необходимо и достаточно наличие 16 микросхемx4, 8 микросхем x8 (это наиболее часто встречаемый вариант) или 4 микросхем x16.

Оставшийся параметр — глубина модуля, являющийся характеристикой емкости (вместимости) модуля памяти, выраженной в количестве «слов» определенной ширины, вычисляется,  простым делением полного объема модуля (выраженного в битах) на его ширину (разрядность внешней шины данных, также выраженную в битах).  Соответственно, произведение ширины на глубину дает полную емкость модуля и определяет его организацию, или геометрию.

Возвращаясь к физическим банкам модуля памяти, заметим, что при использовании достаточно «широких» микросхем x8 или x16 ничего не мешает поместить и большее их количество, соответствующее не одному, а двум физическим банкам — 16 микросхем x8 или 8 микросхем x16. Так различают однобанковые (или «одноранковые», single-rank) и двухбанковые («двухранковые», dual-rank) модули. Двухбанковые модули памяти наиболее часто представлены конфигурацией «16 микросхем x8», при этом один из физических банков (первые 8 микросхем) расположен с лицевой стороны модуля, а второй из них (оставшиеся 8 микросхем) — с тыльной. Наличие более одного физического банка в модуле памяти нельзя считать определенным преимуществом, т.к. может потребовать увеличения задержек командного интерфейса.

Микросхема SPD в модулях памяти

Еще до появления первого типа синхронной динамической оперативной памяти SDR  стандартом JEDEC предусматривалось, что на каждом модуле памяти должна присутствовать небольшая специализированная микросхема ПЗУ, именуемая микросхемой «последовательного обнаружения присутствия» (Serial Presence Detect, SPD). Эта микросхема содержит основную информацию о типе и конфигурации модуля, временных задержках (таймингах), которых необходимо придерживаться при выполнении той или иной операции на уровне микросхем памяти, а также прочую информацию, включающую в себя код производителя модуля, его серийный номер, дату изготовления и т.п. Также последние версии стандарта SPD модулей памяти DDR2, DDR3 включают в себя данные о температурном режиме функционирования модулей, которые могут использоваться, например, для поддержания оптимального температурного режима посредством управления синхронизацией (регулированием скважности импульсов синхросигнала) памяти (так называемый «троттлинг памяти», DRAM Throttle).

Модули памяти.

В обычных современных компьютерах в качестве основной памяти используются модули памяти DIMM (Dual In-Line Memory Modules). Модуль памяти представляет собой "сборку" на печатной плате, состоящую из нескольких микросхем памяти. Кроме того, на модуле расположена небольшая энергонезависимая память для хранения конфигурационной информации (SPD). Это  микросхема с небольшим числом выводов. В случае буферизированных модулей, имеются микросхемы буферов.

Рис. 11.

Ширина шины данных в простых DIMM равна 64 линии (разрядность 64 бит). В модулях с коррекцией ошибок (ECC) - 72 линии (64 бита данных и 8 бит для коррекции). Обычно микросхемы памяти имеют разрядность 4, 8, 16 бит. Поэтому для получения разрядности 64 бита, необходимой для модуля памяти, используется несколько микросхем: 16 микросхем по 4 бита, 8 микросхем по 8 бит или 4 чипа по 16 бит. Возможно параллельное включение двух наборов микросхем памяти с разбивкой на два банка. При этом каждый из наборов работает независимо от другого. Обычно эти наборы состоят из 8 микросхем по 8 бит и находятся на разных сторонах модуля памяти. Получается так называемый двухсторонний модуль. Такие банки памяти обычно называют физическими. Может быть или 1 банк (односторонний модуль) или 2 банка (двухсторонний модуль). Банки памяти, организованные внутри микросхем, обычно называют логическими. Количество логических банков строго оговорено в спецификации и равно 4. Наличие двух физических банков увеличивает общее количество банков памяти в два раза, с 4 до 8.

Из-за большего количества банков двухсторонний модуль памяти обеспечивает производительность немного выше по сравнению с односторонним. Аналогичная ситуация с количеством модулей. Чем больше модулей памяти, даже для одноканальных чипсетов, тем лучше. Правда необходимо помнить, что увеличение количества микросхем памяти и особенно модулей, дополнительно нагружает линии ввода/вывода. Это не только снижает разгонный потенциал, но и, в некоторых случаях, вызывает необходимость к ухудшению параметров памяти для обеспечения стабильной работы. Если важен разгон, то лучше ограничиться одним односторонним модулем с минимальным количеством микросхем. Если система будет работать без разгона, то лучше двухсторонние модули или даже несколько модулей. Однако не стоит ожидать большого прироста производительности. Кроме того, эффект зависит от возможностей чипсетов.

Структурные отличия модулей  и DR DRAM иллюстрирует рисунок 12.

Рис. 12.

Встроенная терминация (согласование). Внешняя калибровка формирователя. Рассеиваемая мощность

Любой сигнал, распространяющийся по реальным проводникам, отражается от различных неоднородностей, в частности от концов проводника; при этом отраженные сигналы взаимодействуют с основным и друг с другом, создавая некоторую интерференционную картину. Практически это означает появление шума, ухудшающего качество сигнала, что, в конце концов, может сделать невозможной передачу данных по шине. Для борьбы с отражениями применяется терминация. В простейшем случае поступают так: на концах шины устанавливают резисторы и заземляют их либо подключают к источнику напряжения. При определенном значении сопротивления (равном характеристическому импедансу шины) резистор поглощает (терминирует, вот откуда зловещий термин) сигнал, и отражения не происходит. Для шины памяти SDR и DDR  терминаторы устанавливаются на материнской плате (резисторы можно увидеть между слотами DIMM); на схеме видно, что это может приводить к отражениям от неактивного в данный момент микросхемы памяти.

Рис. 13.

Память DDR2I терминирует сигналы шины данных, строба данных и маски записи внутри кристалла микросхемы. Кроме снижения шумов, такой подход удешевляет разработку и снижает стоимость материнских плат. Далее, для уменьшения влияния задержки распространения сигнала по трассе в при использовании памяти DDR2I, в отличие от DDR, применяется двунаправленное дифференциальное стробирование сигналов данных. При пониженном напряжении и росте частоты на линиях шины усиливается перекос (skew) восходящего и нисходящего сигналов, а также происходят всплески напряжения, превышающие установленные пределы. Для борьбы с этими неприятными эффектами используется внешняя калибровка (подстройка) импеданса формирователя — OCD. Механизм этот программируемый, контроллер может начать повторную калибровку полного сопротивления в любой момент. Калибровка с помощью внешнего прецизионного резистора вдобавок позволяет нивелировать различия микросхем от разных производителей и в конечном счете снижает перекосы сигналов.

Рис. 14.

Память FB-DIMM


Поддержка FB-DIMM появилась в серверах и рабочих станциях главным образом из-за необходимости установки в них значительных объёмов памяти. Дело в том, что контроллер памяти не мог работать с большим количеством традиционных модулей из-за достаточно сильной электрической нагрузки, требуемой для достижения стабильной работы каждого модуля на высокой частоте. Например, поддержка 64 Гбайт памяти DDR2  требовала  установки в системе 16 модулей памяти, с которыми традиционный контроллер не мог совладать практически наверняка, даже при условии использования регистровых модулей DIMM. Поэтому фирма Intel решила перейти с привычного параллельного дизайна шины памяти к последовательному. FB-DIMM были частью этой концепции: каждый такой модуль объединяет микросхемы памяти DDR2 , которые подключаются к последовательной шине посредством устанавливаемого на каждом модуле дополнительного микросхемы AMB (Advanced Memory Buffer).

Рис. 15. Полностью буферированная память.

У этого подхода есть и обратная сторона. Во-первых, подсистема памяти, построенная на микросхемах памяти FB-DIMM, имеет гораздо большую латентность, которая повышается из-за добавления на пути данных от контроллера памяти   DDR2  до процессора дополнительного контроллера AMB. Кроме того, AMB представляет собой достаточно сложное устройство, которое при своей работе потребляет заметное количество энергии и ощутимо нагревается. Поэтому все модули FB-DIMM потребляют порядка 3-6 Вт каждый и должны оснащаться теплорассеивателями (рис. 16).


Рис. 16.

Топологии подсистемы памяти

На рис. 17 приведена структуры «Fly-by» построения подсистемы оперативной памяти с микросхемами DDR2 и DDR3.

Рис. 17. Структуры Fly-by построения подсистемы оперативной памяти с микросхемами DDR2 и DDR3

Память DDR4

Как и почему  память DDR3 тормозит появление памяти DDR4

Переход на новый стандарт памяти происходит не по приказу свыше или чьему-то капризу, а в связи с неспособностью продуктов предыдущего поколения справляться с поставленными задачами. То есть, потребность в памяти DDR4 возникнет сразу же после того, как память DDR3 полностью исчерпает свои возможности.

Именно в этом и заключается ключевая интрига с переносом сроков внедрения памяти DDR4 на более поздние сроки, нежели планировалось ранее.

По состоянию на 2013 г. возможности памяти  DDR3 вряд ли можно назвать исчерпавшими себя,  так что пока продолжается развитие этого стандарта и дальше. И чем больше удастся "выжать" из памяти DDR3, тем дальше будут переноситься сроки внедрения памяти DDR4. На рис. 18 приведены частоты и годы внедрения  памятей разлмчного типа.

Рис. 18. Частоты и годы внедрения  памятей разлмчного типа.

Посмотрим на сложившуюся ситуацию. По традиции, производительность нового поколения памяти обычно стартует с тех позиций, на которых "захлебнулось" предыдущее поколение.  Напомним, что  память DDR3 стартовала с отметки DDR3-1066, на которой остановилось развитие  памяти DDR2 (DDR2-400/1066).

На сегодняшний день память DDR3 представлена очень широко (DDR3-1600, встречаются DDR3-1866,  есть  нестандартные варианты типа  DDR3-2000).

Ранее ожидалось, что возможности массовой памяти DDR3 будут исчерпаны где-то в районе производительности уровня DDR3-1600. С этой отправной точки предполагалось восхождение памяти DDR4, однако совсем недавно спецификации DDR3 пополнились стандартизированной версией DDR3-2133.

Рис. 19.

Таким образом, при наличии сертифицированных стандартных модулей DDR3-2133 появление памяти стандарта DDR4-1600 попросту теряет всякий смысл.  Современный, более реалистичный график предполагает, что в рамках стандарта DDR4 скорость модулей составит от DDR4-2133 до DDR4-4266.

Однако растущая производительность – не единственный "козырь", продлевающий жизнь памяти стандарта DDR3 и отдаляющий появление памяти DDR4. Ещё один важный момент – энергопотребление, напрямую связанное с напряжением питания микросхем  памяти. Первоначально предполагалось, что напряжение питания  памяти DDR4 составит 1,2 В, и затем появятся новые поколения микросхем с питающим напряжением 1,1 В и 1,05 В. В то же время, для памяти DDR3, впервые представленной в 1,5 В варианте, развитие  должно была закончиться на  1,35 В микросхемах. Однако выпуск низковольтной памяти DDR3 с напряжением питания всего 1,25 В делает появление 1,2 В памяти DDR4 преждевременным, так как более высокие частоты работы памяти значительно увеличивают энергопотребление.

На рис. 20 показано относительное энергопотребление микросхем памятей DDR3 и  DDR4.

Рис. 20. Относительное энергопотребление микросхем памятей DDR3 и  DDR4.

Третий важный момент – растущая ёмкость модулей, и здесь память DDR3 вновь не готова сдавать позиции. Появление низковольтных микросхем памяти  DDR3 емкостью 8 Гбит позволяет наладить выпуск очень ёмких модулей памяти с низким энергопотреблением, что также делает появление DDR4 в ближайшее время неактуальным .

Рис. 21.

Структура  и топология  подсистем памяти с микросхемами памяти DDR4

При переходе от памяти DDR2 к DDR3 разработчиками стандарта был сделан революционный шаг. Типичная для памяти DDR2 топология подключения шины памяти "звёздочкой" была заменена на сетевую (Fly-by) топологию командной, адресной и управляющей шин, с внутримодульной (On-DIMM) терминацией и прецизионными внешними резисторами (ZQ resistors) в цепях калибровки.

На  рис. 22 приведены структуры построения подсистемы оперативной памяти с микросхемами DDR4.

Рис. 22. Структуры построения подсистемы оперативной памяти с микросхемами DDR4.

Из этого следует, что подсистема памяти DDR4 позволит поддерживать только один единственный модуль памяти на каждый канал. Вряд ли это окажет существенное воздействие на рынок мобильных и настольных ПК, хотя увеличение объёмов оперативной памяти не помешает никому, однако наиболее важным этот вопрос будет для серверного рынка. Как же наращивать количество памяти в условиях таких жёстких канальных ограничений?

Выходов из ситуации на сегодняшний день придумано несколько. Первый – самый логичный: необходимо наращивать ёмкость собственно  микросхем и модулей памяти. Один из перспективных способов – изготовление многоярусных микросхем по технологии TSV (Through-Silicon Via), которую также называют "объёмной", или просто 3D.

С многослойными (MLP) микросхемами флэш-памяти технология TSV имеет лишь отдалённое сходство, однако понять суть формирования микросхемы в самых общих чертах такая аналогия помогает. Идея не нова, так как ещё в 2007 году компания Samsung Electronics объявила о выпуске первых многоярусных 512-Мбит микросхем DRAM по технологии TSV.

Рис. 23.

Именно эту технологию планирует использовать для выпуска DDR4 консорциум из компаний Elpida Memory, Powertech Technology и United Microelectronics (UMC).

Рис. 24.

Рис. 25.

Ещё один хорошо известный и уже зарекомендовавший себя способ - использование техники так называемой "разгружающей памяти" - LR-DIMM (Load-Reduce DIMM). Суть идеи состоит в том, что в состав модуля памяти LR-DIMM входит специальная микросхема (или несколько микросхем), буферизирующих все сигналы шины и позволяющая увеличить количество поддерживаемой системой памяти.

Рис. 26.

К примеру, на сегодняшний день компании Samsung  и Micron уже освоили технологию выпуска модулей памяти стандарта DDR3 LR-DIMM объемом 32 Гбайт.

Ничто не ограничивает применение этой технологии и при выпуске памяти DDR4. Правда, не стоит забывать про, пожалуй, единственный, но от этого не менее существенный недостаток LR-DIMM: буферизирование неизбежно ведёт к  дополнительному увеличению латентности, которая у памяти DDR4 по определению будет и без того немаленькая.

Рис. 27.

Для сегмента серверных и и высокопроизводительных систем, где востребован очень большой объём памяти, предлагается совершенно иной выход из ситуации. Здесь предполагается использование высокоскоростной коммутации специальными многовходовыми микросхемами-коммутаторами.

Рис. 28.

Как известно, CAS-латентность (задержка между отправкой в память адреса столбца и началом передачи данных)  памяти DDR3 составляет 5 – 16 тактов, для GDDR5, соответственно, 5 - 36 тактов; при этом tRFC для памяти DDR3 составляет 90 – 350 нс. В частности, для памяти DDR3-2133 типичные тайминги составляют 12-12-12 против 9-9-9 многих модулей DDR3-1333.

Буфера предвыборки 8n, рассчитанную на выборку 8  слов данных за одно обращение к памяти у DDR3, действительно сменит Prefetch16 у DDR4, однако как именно это скажется на общей производительности, без знания остальных ключевых характеристик памяти DDR4 оценить трудно.

Выводы

Процесс перехода с памяти DDR3 на память DDR4 будет более сложным и более продолжительным, нежели в своё время переход с памяти DDR2 на память DDR3.

За счёт изменения топологии и структуры памяти сложнее придётся и производителям системных плат, и системным интеграторам. Разумеется, достанется и конечным пользователям, которые в итоге оплатят весь этот "праздник" перехода на новые стандарты из своего кошелька.

Острую необходимость в более производительной памяти сегодня удаётся снизить благодаря расширению спецификаций памяти DDR3 до поддержки режима DDR3-2133, что уменьшает необходимость срочного появления нового поколения памяти. Первоначальная версия памяти DDR4-1600 вряд ли вообще будет выпущена ввиду неактуальности.

На сегодняшний день предполагается, что модули памяти DDR4 будут представлены  в вариантах от DDR4-2133 до DDR4-4266.

Затем стартует многолетняя эпопея по постепенному замещению памяти DDR3 на память DDR4, которая, по предварительным оценкам, проявит себя всерьёз к 2015 году, и затем ситуация начнёт развиваться по нарастающей.

Сравнительная характеристика основных типов памяти

С точки зрения пользователя ПК главная характеристика памяти - это скорость или, выражаясь другими словами, ее быстродействие.

Время доступа к памяти непостоянно и в зависимости от ряда обстоятельств варьируется в очень широких пределах. Наибольшая скорость достигается при последовательном чтении, а наименьшая - при произвольном чтении.

Современные модули памяти имеют несколько независимых банков и потому могут обрабатывать более одного запроса одновременно. Таким образом, несмотря на то, что выполнение каждого отдельно взятого запроса по-прежнему будут занимать весьма внушительное время (конденсаторное ядро так ведь и не было переработано!), запросы могут следовать непрерывно. А раз так, - непрерывно будут приходить и ответы.

Теоретически все так и есть, но на практике возникает множество затруднений. Основной камень преткновения - фундаментальная проблема зависимости по данным. Рассмотрим следующую ситуацию. Пусть ячейка N1 хранит указатель на ячейку N2, содержащую обрабатываемые данные. Пока не будет  получено содержимое ячейки N1, нельзя послать запрос на чтение ячейки N2, поскольку, еще не известен ее адрес. Следовательно, производительность памяти в данном конкретном случае будет определяться не пропускной способностью, а ее латентностью, т.е. полным временем доступа к одной ячейке.

Причем, описываемый случай отнюдь не является надуманным, скорее наоборот. Это - типичная ситуация. Базовые структуры данных - деревья и списки - имеют ярко выраженную зависимость по данным, т.к. объединяют свои элементы именно посредством указателей, что сводит на нет весь выигрыш от параллелизма. Большинство функции штатных библиотек Си/Си++ также имеют зависимость по данным и не могут обрабатывать их параллельно.

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

Наконец, в-третьих, команды предвыборки до сих пор не поддерживаются ни одним оптимизатором, и вряд ли будут поддерживаться в ближайшем будущем. Ручная же оптимизация - слишком сложна и трудоемка, чтобы стать массовой.

Короче говоря, теоретическая пропускная способность памяти, заявленная производителями, совсем не то же самое, что и реальная производительность.  "Официальная" пропускная способность - это абстракция чистейшей воды, интересная скорее с маркетинговой точки зрения, но  бесполезная для конечного пользователя.

Контрольные вопросы

  1.  Как работает динамическая память (DRAM)?
  2.  Как логически организованы  микросхемы памяти
  3.  Интерфейс микросхемы памяти
  4.  Банки памяти
  5.  Различия между  памятями SDR,  DDR, DDR2 , DDR3
  6.  Память DDR3
  7.  Организация модулей  памяти
  8.  Топологии подсистемы памяти
  9.  Память DDR4
  10.  Структура  и топология  подсистем памяти с микросхемами памяти DDR4
  11.  Терретическая и реальная производительность основных типов памяти

Структуры  персональных компьютеров

Структуры компьютеров с двумя мостами

На рис.  1. приведены структуры компьютеров на базе процессоров  фирмы Intel Core 2 Duo, Core 2 Quad  и двумя «мостами» из  набора системной логики  Р35.

Рис. 1. Пример  структуры персональных компьютеров на базе процессоров Core 2 Duo, Core 2 Quad фирмы Intel и набора системной логики Р35

Набор системной логики состоит из двух микросхем – «северного моста»  и «южного моста».  

В «северном мосту» находятся:

контроллер оперативной памяти. Он может быть одно- или многоканальным.

контроллер интерфейса с видеоадаптером;

контроллер интерфейса связи с «южным мостом»;

контроллер интерфейса связи с системной шиной;

коммутатор.

В «южном мосту» находятся все контроллеры интерфейсов внешних периферийных устройств.

О переносе контроллера оперативной памяти из «северного» моста в процессор

Фирма AMD первой перенесла контроллер оперативной памяти из «северного» моста в процессор. Это позволило сократить пути основного потребителя ресурсов памяти (а это и есть процессор) к оперативной памяти и, соответственно, уменьшить задержки при работе с оперативной  памятью.

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

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

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

От интеграции контроллера памяти в процессор не только сокращаются задержки в работе с памятью (теперь запросы на запись/считывание минуют внешний северный мост), но и существенно сокращаются шансы на то, что чипсет будет тормозить общую производительность компьютера.

Во всех современных процессорах контроллер оперативной памяти встроен в микросхему процессора.

Компьютеры  с процессорами  со структурой Nehalem и двумя «мостами»

Структура компьютера  с процессором Core i7 и двумя «мостами» из набора системной логики Intel X58  приведена на рис. 2.

Рис. 2. Структурная схема компьютера с процессором Core i7 и набором системной логики Intel X58.

Структуры компьютеров с одним «южным» мостом

Структура компьютера  с процессорами Core i5, i7 и одним «южным мостом»   системной логики Intel H57  приведена на рис. 3.

Рис. 3. Структура компьютера  с процессорами Core i5, i7 и «южным мостом»  

В приведенном на рис. 3 процессоре реализованы:

ядра;

контроллер оперативной памяти (в данном примере он двухканальный);

контроллер интерфейса PCI-E 16;

видеоядро.

Как правило,  интерфейс PCI-E 16 используется для подключения внешних видеокарт.

На рис. 4 показаны различия в структурах как процессоров, так и компьютера в целом при переходе от структуры с двумя «мостами» к структуре с одним «мостом».

Рис. 5.

Структуры  ПК с процессорами Sandy Bridge

На рис. 6. 7.8  приведены структуры компьютеров с одним «мостом».

Рис. 6.

Рис. 7

Рис. 8

Во всех процессорах Sandy Bridge для персональных компьютеров графика  встроена в кристалл процессора.

Фирма  Intel предпочитает использовать для новых южных мостов термин PCH — Platform Controller Hub,  а фирма AMD  термин  FCH — Fusion Controller Hub. С технической точки зрения, микросхемы обеих фирм  похожи друг на друга как близнецы-братья.

Cтруктуры персональных  компьютеров на базе процессоров фирмы AMD

Обобщенная структура персонального компьютера на базе процессоров фирмы AMD с двумя «мостами» приведена на рис. 9,  реальная структура компьютера на базе процессоров Phenom  и набора системной логики   790GX – на рис. 10

Рис. 9 . Обобщенная структура персонального компьютера с двумя «мостами» на базе процессоров фирмы AMD.

Рис. 10.  Структура ПК на базе процессоров Phenom  и набора системной логики   790GX.

Структура персонального компьютера с одним  «мостом» приведена на рис. 11.

Во всех новых процессорах фирмы AMD для персональных компьютеров графика  встроена в кристалл процессора.

Рис. 11

«Южный мост»  AMD A75 поддерживает:

все процессоры для Socket FM1;

до четырех портов PCIe 2.0 х1;

до трех слотов PCI;

шесть портов Serial ATA с поддержкой скоростей до 600 МБ/с, режима AHCI и функций вроде NCQ, с возможностью индивидуального отключения, а также с поддержкой eSATA и разветвителей портов (для последних поддерживается FIS-based (frame information structure) switching, что в первом приближении позволяет работать со всеми подключенными к порту дисками параллельно);

возможность организации RAID-массива уровней 0, 1 и 0+1 (10);

4 порта USB 3.0 (один xHCI-контроллер);

10 портов USB 2.0 (на двух хост-контроллерах EHCI) с возможностью индивидуального отключения;

два дополнительных порта USB 1.1 (на отдельном UHCI-контроллере) для подключения низкоскоростной периферии;

High Definition Audio (7.1);

встроенный SD-контроллер;

обвязку для низкоскоростной и устаревшей периферии.

Примеры традиционной схемы компонентов на материнской плате приведены на рис. 12 и 13.

Рис. 12

Рис. 13.

Контрольные  вопросы

  1.  Из каких микросхем систоит  набор системной логики?
  2.  Какие функции «северного» моста в компьютере?
  3.  Какие функции «южного» моста в компьютере?
  4.  Почему в компьютерах использовали 2 моста?
  5.  Чем обусловлен перенос контроллера оперативной памяти из «северного» моста в процессор»?
  6.  Какие функции интерфейса PCI-E в компьютере?

О производительности компьютеров

1. Пиковая производительность ВС

Исторически первым способом оценки производительности было определение пиковой и технической производительности, представляющей собой теоретический максимум быстродействия компьютера при идеальных условиях. Данный максимум определяется как число операций, выполняемое в единицу времени всеми имеющимися в компьютере обрабатывающими логико-арифметическими устройствами. В современных условиях значение пиковой производительности измеряется в миллионах операций в секунду MIPS (million instruction per second) или миллионах операций с плавающей точкой в секунду MFLOPS (millions floating point operations per second). Пиковое быстродействие достигается при обработке бесконечной последовательности не связанных между собой и не конфликтующих при доступе в память команд (т.е. когда результат любой операции не зависит от действий, выполненных другими командами). При этом в современных компьютерах предполагается, что все операнды выбираются из внутри кристальной кэш-памяти данных, а команды — из кэш-памяти команд. Разумеется, на практике ни одна система не в состоянии работать сколько-нибудь длительное время с пиковой производительностью, хотя и может приближаться к этой величине.

Пиковая производительность является единственной по-настоящему объективной оценкой (для ее определения необходимо знать всего несколько параметров компьютера) и совершенно не зависит от выполняемой программы. Речь идет о тактовой частоте процессора, которая для подавляющего большинства современных компьютеров определяет темп формирования результатов на выходе арифметического конвейера, о числе арифметических конвейеров и о числе процессоров в системе. Чтобы определить пиковую производительность машин, надо умножить тактовую частоту на количество параллельно выполняемых операций. Например, арифметическое устройство компьютера каждый такт может формировать один результат 64-битной операции с плавающей точкой или два 32-разрядных результата целочисленных операций. Следовательно, для компьютера с тактовой частотой 2000 МГц пиковая производительность равна 2000 MFLOPS при выполнении вычислений с плавающей точкой и 4000 MIPS при целочисленной 32-разрядной обработке. Умножив это значение на число процессоров в компьютере, получим его пиковую производительность при обработке соответствующих операндов.

Значения пиковой производительности, при всей простоте их получения, могут оказаться чрезвычайно полезными при обсуждении достоинств компьютеров. Особенно удобно использовать показатели предельного быстродействия для сравнения возможностей процессоров в первом приближении. Американские специалисты по контролю за экспортом вооружений при оценке уровня производительности компьютеров используют показатель составной теоретической производительности (СТР), измеряемой в Mtops — миллионах теоретических операций в секунду. СТР зависит только от аппаратных средств компьютера (тактовой частоты, набора функциональных устройств, пропускной способности и набора внутренних шин, длины разрядной сетки и так далее).

Однако сравнение производительности компьютеров с использованием пиковых значений производительности не всегда приводит к адекватным результатам. Один и тот же результат, например, сложение элементов двух массивов, размещенных в памяти, может быть получен с использованием разного числа команд и RISC и CISC процессорах. Разные форматы команд имеют разную длительность исполнения, и время исполнения последовательности команд зависит от конкретного места каждой команды в последовательности. Не следует забывать также о влиянии разрядности обрабатываемых чисел, чтобы избежать, например, некорректного сравнения производительности при обработке 32- и 64-разрядных данных. При появлении суперкомпьютеров типа CRAY-1 была введена единица измерения производительности, выражаемая числом «результатов» с плавающей точкой в единицу времени. Введение этого показателя обосновывалось тем, что есть собственно основные, необходимые операции с плавающей точкой, которые формируют результат вычислений, и есть вспомогательные операции по организации вычислений, которые не должны учитываться в полезной производительности. Например, при умножении матриц важны только операции с плавающей точкой получения значений элементов результирующей матрицы, а операции с фиксированной точкой, формирующие адреса элементов матриц, счетчики циклов и так далее — это внутренняя организация компьютера. Однако, явная проблемная ориентация этого показателя производительности на научно-технические расчеты не сделала его сколько-нибудь распространенным.

2. Реальная производительность

При выполнении реальных прикладных программ эффективная (реальная) производительность компьютера может весьма существенно (до нескольких раз) быть меньше пиковой. Это объясняется тем, что современные высокопроизводительные процессоры имеют сложную структуру (суперконвейерная и суперскалярная обработка, многоуровневая память, и т.д.). Характеристики их функционирования на уровне внутренних устройств существенно зависят от программы и обрабатываемых данных. Поэтому невозможно с необходимой точностью оценить производительность только на основании тактовой частоты их работы, числа затрачиваемых на выполнение одной команды тактов процессора и числа устройств обработки.

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

 Если каким-либо образом определить абсолютную производительность эталонного компьютера, выражаемую числом выполняемых в секунду вычислительных операций, то не составит труда перейти от индексов производительности к абсолютным значениям оценок производительности других компьютеров.

3. Способы измерения реальной производительности

При оценке производительности на тестах приходится решать три проблемы, связанные с анализом результатов контрольного тестирования производительности:                                 

отделение показателей, которым можно доверять безоговорочно от тех, которые должны восприниматься с известной долей настороженности (проблема достоверности оценок);          

• выбор контрольно-оценочных тестов, наиболее точно характеризующих производительность при обработке типовых задач пользователя (проблема адекватности оценок);                   

• правильное истолкование результатов тестирования производительности, особенно если они выражены в довольно экзотических единицах типа MWIPS, Drystones/s и т.д. (проблема интерпретации).

Существующие тестовые наборы можно разбить на три группы. Первую группу тестов измерения производительности составляют тесты производителей, разрабатываемые компаниями-изготовителями компьютеров для «внутреннего» применения — оценивания качества собственных продуктов. Главная особенность данных тестов заключается в том, что они ориентированы на сравнение ограниченного множества однотипных компьютеров, часто относящихся к одному семейству. Эти тесты позволяют разработчикам компьютеров оптимизировать структурно-технические решения. Например, для оценки производительности процессоров с архитектурой х86 компания Intel в 1992 году предложила индекс производительности iCOMP (Intel Comparative Microproccss Performance). В качестве эталонного процессора принят 486 SX-25, значение индекса для которого равно 100. Индекс iCOMP определяется при выполнении смеси операций, состоящей из 67% операций над 16 разрядными целыми, 3% операций над 16 разрядными числами с плавающей точкой, 25% - над 32 разрядными целыми и 5% - над 32 разрядными числами с плавающей точкой. К примеру, индексы iCOMP для процессоров 486 SX2-50, Pentium-100 и Pentium-166 равны 180,  815 и 1308 соответственно. Следует отметить, что индекс iCOMP оценивает производительность процессора как такового, а не вычислительной установки, включающей еще оперативную память и внешние устройства.    

В фирме IBM имеются специализированные тестовые пакеты для измерения производительности компьютеров с архитектурой мэйнфреймов семейства System/370 и System/390, а также тесты для компьютеров с архитектурой AS/400

Тесты производителей являются почти идеальным средством оценивания быстродействия и технико-экономических показателей систем с одной и той же архитектурой, но разными средствами ее реализации, однако они не могут быть в чистом виде использованы для других компьютеров — сказывается слишком явная ориентация тестов на конкретную «фирменную» архитектуру. Эти тесты используются создателями систем оценки различных вариантов реализации.

Вторую группу составляют стандартные тесты. Стандартные тесты, разработанные для сравнения широкого спектра компьютеров, часто претендуют на роль полностью универсальных средств измерения производительности. В основе подобных амбиций лежит то, что тесты этой категории - продукт деятельности независимых аналитиков (например, Джека Донгарры, предложившего тестовый пакет Unpack) или групп, объединяющих крупнейших производителей компьютеров (SPEC, TPC), что практически исключает возможность ориентации стандартного тестa на конкретного поставщика компьютеров. Например, для оценки серверов, обрабатывающих транзакции в реальном времени, в так называемых OLTP-системах, используется тестовый набор компании Transaction Processing Performance Council (TPC-C). Производительность серверов оценивается числом транзакций, исполняемых за минуту (tpmC).

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

Сегодня наиболее распространенными являются наборы тестов Unpack, а также наборы тестов компании SPEC (Standard Performance Evaluation Corporation) - SPEC (89, 92 и 95) [82] и тесты Transaction Processing Performance Council [83], которые и будут рассмотрены ниже.

4. Тесты Linpack

Этот набор тестов представляет собой совокупность программ решения задач линейной алгебры. В качестве параметров используются: порядок матрицы (например, 100х100, 1000х1000), формат значений элементов матриц (одинарная или двойная точность представления элементов матриц), способ компиляции (с оптимизацией или без оптимизации), а также возможность применения оптимизированной библиотеки стандартных функций. Вообще говоря, на тестах Unpack при больших размерностях обрабатываемых матриц почти все компьютеры демонстрируют производительность в диапазоне от 0.8 до 0.95 от пикового значения. Это наблюдение объясняется тем, что проблемная ориентация большинства современных компьютеров - расчет по формулам при решении хорошо формализованных задач.

По результатам тестирования с использованием тестов Linpack с июня 1993 года в университете Маннгейма (Mannheim) в Германии и в Netlilb в США ведется список ТОР 500, включающий 500 самых производительных компьютерных установок в мире. Этот список легко найти в Internet по его названию.

5. Пакеты тестовых программ SPEC XX

Пакет SPEC 89

Пакет SPEC 89 включает два тестовых набора - Cint89, состоящий из четырех программ целочисленной обработки, и Cfp89, объединяющий шесть программ со значительным объемом операций над числами с плавающей точкой двойной точности. Все десять программ представляют .собой достаточно сложные коды на языках С и FORTRAN с широким спектром решаемых задач - от оптимизации представлений функций булевой логики в программируемых логических схемах до моделирования замещения атомов в квантовой химии.

Методика оценки производительности SPEC 89 предполагает формирование десяти дифференциальных оценок SPECratio., каждая из которых определяется как отношение времени выполнения i-й программы из наборов Cint89 и Cfp89 на тестируемом компьютере ко времени выполнения той же программы на ЭВМ DEC VAX 11/780.

Интегральной характеристикой производительности компьютера служит показатель SPECmark, являющийся средним геометрическим всех десяти частных оценок SPECratio. К параметру SPECmark добавлены ещё две оценки - SPECint89 и SPECfp89, раздельно характеризующие быстродействие компьютера при обработке целочисленных данных и вещественных чисел. Принцип расчета этих показателей не отличается от вычисления SPECmark: SPECint89 представляет собой среднее геометрическое частных оценок SPECratio для четырех программ из набора Cint89, а SPECfp89 - аналогичную величину для шести программ из состава Cfp89.

Пакет тестовых программ SPEC 92

Этот набор расширяет круг тестируемых функций по сравнению со SPEC 89. Методика расчета основных характеристик производительности в SPEC 92 не претерпела никаких принципиальных изменений. Показатели SPECint92 и SPECfp92 по-прежнему определяются средними геометрическими частных оценок SPECratio, полученных при тестовом прогоне программ из наборов Cint92 и Cfp92 (конечно, с учетом увеличения числа тестовых программ).

Пакет оценочных программ Cint92 предназначен для оценки производительности вычислительных систем при выполнении целочисленных операций преимущественно в коммерческой области применения. В его состав входят 6 эталонных тестов, написанных на языке С и представляющих собой задачу из теории сетей, интерпретатор языка Lisp, задачу логического проектирования, Unix - утилиту упаковки тестового файла размером 1 Мбайт, который 20 раз подвергается сжатию, операции со строками и столбцами электронной таблицы и компилятор языка С.

Пакет оценочных программ Cfp92 предназначен для оценки производительности ВС при выполнении операций с плавающей точкой (преимущественно в технической и научной областях применения).

В его состав входят 14 реальных прикладных программ, две из которых написаны на языке Си и на языке Фортран. В пакет входят программы схемного проектирования, моделирования термодинамики ядерного реактора методом Monte-Carlo, задачи квантовой химии и физики, решение уравнений Максвелла, преобразование координат, трассировка оптических лучей, задачи робототехники и нейросетей, моделирования человеческого уха, решение уравнений Навье-Стокса для определения параметра межгалактического газа, семь библиотечных функций обработки матриц (умножение, обращение и т.д.) и ряд других.

Но одно качественное новшество в SPEC 92 все-таки введено. Речь идет о характеристиках мультипрограммной обработки SPECrate, формируемых в рамках метода однородной нагрузки. Суть последнего заключается в следующем: тестируемая ВС выполняет задание, состоящее из множества копий одной программы, а показателем производительности многопроцессорной обработки служит количество копий, завершенных за определенный интервал времени. Для получения оценки SPECrate используются те же программы, что и для расчета показателей SPECint92 и SPECfp92. Разница только в том, что тестовый модуль реализуется как несколько копий, образующих одно задание, а результатом измерений является нормированное общее время выполнения всех копий задания. Подобной процедуре подвергается каждая из 20 тестовых программ, что позволяет получить шесть частных оценок SPECratio, для программ целочисленной обработки и 14 - для программ обработки вещественных чисел.

Таким образом, SPECrateint92 и SPECratefp92 оценивают среднюю скорость выполнения задач в многопроцессорном режиме работы системы. Кроме того, эти показатели позволяют получить представление о возможностях компилятора по организации параллельного мультизадачного кода, а также операционной системы - по эффективному динамическому распределению ресурсов системы (в частности, процессоров) между выполняемыми параллельными программами. Это делает оценки SPECrateint92 и SPECratefp92 особенно представительными для SMP-систем коллективного пользования, работающих в пакетном режиме. Сводные сведения о программах, входящих в SPEC89 и SPEC92 приведены ниже в таблице 1/

Таблица 1. Перечень программ наборов SPEC89, SPEC92

Программа

Тест

Язык

Тип данных

Моделирование ПЛМ (PLA)

89+92

С

ФТ

Lisp-интерпретатор

89+92

С

ФТ

Формирование логических таблиц истинности

89+92

С

ФТ

Unix — утилита упаковки тестового файла размером 1 Мбайт, который 20 раз

подвергается сжатию

92

С

ФТ

Операция со строками и столбцами электронной таблицы

92

С

ФТ

Компилятор GNU, трансляция 19 программ на С в оптимизированный код ассемблера

89+92

С

ФТ

Моделирование аналоговых цепей с высокой интенсивностью обменов с памятью

89+92

Фортран

ПТ, ДВ

Моделирование термодинамики ядерного реактора методом Монте-Карло; содержит большое число ветвлений и коротких циклов

89+92

Фортран

ПТ, ДВ

Задача квантовой химии для системы из 500 атомов

92

Фортран

ПТ, ДВ

Версия теста Mdijdp2 для одинарной точности

92

Фортран

ПТ

Решение уравнений Максвелла

92

Фортран

ПТ, ДВ

Генерация сетки при моделировании процессов обтекания; программа ориентирована на тестирование параллельных систем

89+92

Фортран

ПТ, ДВ

Моделирование управления движением робота с использованием видеосистемы

92

С

ПТ

Решение сеточной задачи shallow-water для сетки 256х256

92

Фортран

ПТ

Задача квантовой физики вычисления массы элементарных частиц с использованием метода Монте-Карло; хорошо векторизуется и ориентирована на тестирование параллельных систем

92

Фортран

ПТ, ДВ

Решение уравнений Навье-Стокса для определения параметра межгалактического газа; программа хорошо векторизуется и ориентирована на тестирование параллельных систем

92

Фортран

ПТ, ДВ

Семь библиотечных функций обработки матриц (умножение, обращение и т.д.)

89+92

Фортран

ПТ, ДП

Моделирование процесса замещения атомов ни сериях Гаусса; программа плохо распараллеливается и содержит большой объём ввода/вывода

89+92

Фортран

ПТ, ДП

Синтетический тест, имитирующий различные алгоритмы умножения матриц

89

Фортран

ПТ, ДВ

Моделирование уха человека

92

С

ПТ, ДВ

Пакет тестовых программ SPEC 95

Появление нового набора тестовых программ обусловлено развитием микропроцессоров (повышением производительности и увеличением объема внутри кристальной памяти), совершенствованием компиляторов, а также скорректированным после появления SPEC 92 представлением об актуальности различных областей приложений.

Современные микропроцессоры выполняют тесты SPEC 92 в течение интервалов времени от долей секунды до нескольких секунд, что вносит в измерения достаточно большую погрешность. Объем кода программ и данных SPEC 92 таков, что программы и данные могут разместиться в кэш-памяти процессора. Это вообще не позволяет получить сколько-ни-будь достоверные оценки производительности.

Индексы производительности в SPEC 95 даются по отношению к эталонной процессоре SPARC-station 10/40 в конфигурации с кэш-памятью второго уровня.

Используются два тестовых набора CINT 95 и CFP 95, состоящие из 8 и 10 программ соответственно.

При испытаниях компьютеров формируются:

• индексы производительности SPEC int 95, SPEC fp 95 и SPEC int base 95, SPEC fp base 95 для фиксированной и плавающей точки в режиме компиляции с агрессивной оптимизацией и с консервативной оптимизацией соответственно.

• индексы пропускной способности SPEC int rate 95, SPEC fp rate 95 и SPEC int rate base 95, SPEC fp rate base 95 для оценки многозадачных режимов и SMP архитектур в режиме компиляции с агрессивной оптимизацией и с консервативной оптимизацией соответственно.

Все интегральные индексы производительности формируются как среднее геометрическое индексов по отдельным тестам. Детальную информацию по результатам тестирования и тестам SPEC можно найти на SPEC WWW сайте htpp://www.specbench.org и http://performance.netlib.org/performance/html/spec.html. Корпорация SPEC не дает никаких рекомендаций по установлению соответствия между значениями индексов SPEC 92 и SPEC 95.

Таблица 2. Перечень программ набора CINT 95

Область приложения

Спецификация задачи

Моделирование

Моделирование кристалла Motorola 88100

Компиляция

Компиляция программы на С

и компиляция оптимизированного

кода для процессоров SPARC

Искусственный интеллект

Игра Го - игра сама против себя

Компрессия

Компрессия текстового файла размером 16 Мбайт

Интерпретация

Lisp-интерпретатор

Обработка изображений

Сжатие графических объектов (JPEG) с различными параметра

Манипулирование текстовыми строками

Shell-интерпретатор

Базы данных

Построение таблиц и манипулирование с таблицами

 

Таблица 3. Перечень программ набора CFP

Область приложения

Спецификация задачи

Гидродинамика, геометрический аспект

Генерация двумерной координатной сетки в произвольной области

Предсказание погоды

Моделирование водной поверхности методом конечных элементов (вещественная арифметика с одинарной точностью)

Квантовая физика

Вычисление масс элементарных частиц методом Монте-Карло

Астрофизика

Расчет межгалактических газов по уравнениям Навье-Стокса

Электромагнетизм

Расчет трехмерного поля потенциалов

Гидродинамика

Решение системы уравнений в частных производных

Моделирование

Моделирование турбулентности в кубическом объеме

Предсказание погоды

Вычисление статистики температур, воздушных потоков и уровней загрязнения

Квантовая химия

Порождение потока электронов

Электромагнетизм

Решение уравнения Максвелла

6.  Пакеты тестовых программ ТРС

Для оценки производительности вычислительных систем при работе с базами данных компания Transaction Processing Performance Council предлагает набор спецификаций тестов, используемых для оценки эффективности функционирования в различных режимах обработки данных. Реализации тестов выполняются фирмами, которые согласуют свои тест-программы с ТРС, привлекающей независимых аудиторов для оценки соответствия тест-программ спецификациям.

Набор тестов первоначально включал тесты ТРС-А, ТРС-В, ТРС-С. В дальнейшем он был расширен спецификациями тестов TPC-D и ТРС-Е. Ведутся постоянные исследования по модификации уже существующих и разработке новых спецификаций тестов.

Тесты дают сравнительную оценку по стоимости и производительности совокупности аппаратно-программных средств, включая операционные системы, системы управления базами данных, мониторы транзакций.

Тест ТРС-А используется для оценки эффективности исполнения Транзакций типа «дебит-кредит». При исполнении теста моделируется работа филиальной сети банка по приему-выдаче вкладов клиентов. Клиенты банка имеют счета и балансы этих счетов. В каждом из филиалов банка есть несколько кассиров, каждый из которых имеет некоторую сумму наличных денег. В тесте используется один тип транзакции, задающий манипулирование со счетом клиента. Ведется история реализации транзакций.

Соотношение стоимость/производительность оценивается как стоимость пятилетней эксплуатации всего оборудования и программных средств испытываемой системы, отнесенная к максимальному числу транзакций в секунду, которое способна выполнить система. Тест ТРС-В отличается от теста ТРС-А, другой методикой подсчета стоимости системы. Стоимость системы подсчитывается без стоимости терминалов.

Тест ТРС-С предназначен для оценки эффективности систем при paботе в режиме оперативной обработки транзакций (On Line Transaction ProcessingOLTP). Тест составляет смесь транзакций, характерных для OLTP считывающих и обновляющих содержимое базы данных.

ТРС-С является тестом, при исполнении которого моделируется функционирование нескольких складов компании. Используются операции агрегации, соединения, селекции отношений базы данных. Каждый склад имеет 10 участков, каждый участок — 3000 заказчиков, 10000 наименований товаров. Используется пять типов транзакций: новый заказ, платеж, статус заказа, выполнение заказа, уровень запасов по последним 20 наименованиям запрошенных товаров. Тест оценивает количество транзакций, выполненных в минуту tmpC (transaction-per minute С), а также стоимость одной выполненной транзакции в минуту.

Тест TPC-D используется для оценки эффективности систем поддержки принятия решений с многонаправленными соединениями, сортировками и агрегациями данных отношений. Создаваемая тестом нагрузка существенно отличается от характерного для OLTP потока простых транзакций, обрабатывающих небольшие порции данных. Системам поддержки принятия решений присуще небольшое число сложных взаимосвязанных запросов, обрабатывающих почти всю базу данных. Это запросы типа определения пациентов клиники, имеющих определенный тип заболевания и проживающих в определенном районе. В связи с этим важное значение имеет объем базы данных. В тесте предусматривается 6 градаций объемов базы данных: 1Гбайт, 10Гбайт, 30 Гбайт, 100Гбайт, 300Гбайт, 1Тбайт.

В результате тестирования определяются:

• производительность обработки запросов QppD (Query Processing Performance), измеряемая количеством запросов, которое может быть обработано при монопольном использовании всех ресурсов тестируемой системы;

• пропускная способность системы QthD (Query Throughput), измеряемая количеством запросов, которое система в состоянии совместно обрабатывать в течение часа;

• отношение стоимости к производительности $/QphD, измеряемое как стоимость 5-летней эксплуатации системы, отнесенная к числу запросов, обработанных в час.

7. Замечания о методах оценки производительности

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

Всегда, если известна область применения компьютера, следует отдавать предпочтение не оценке, полученной как среднее геометрическое оценок на разных тестах, а тестам, адекватным области применения.

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

Кризис  оценки производительности персональных компьютеров с использованием бенчмарков

Основная проблема современных ПК состоит в том, что совершенно непонятно, для кого большинство из них предназначены. Даже мейнстримовые конфигурации (не говоря уже о топовых), все детские задачи щёлкают, как белка орехи — а никаких «недетских» задач 99%  ПК ни разу за весь свой период существования  ни разу не решали. Для перемещения (сёрфинга) по интернету, чтения почты, написания текстов и составления простеньких электронных таблиц, а также обработки любительских фотографий, сжатия в формат MP3 десятка CD с любимыми песнями, и прочих потребительских потребностей — вполне хватит простого процессора. Поэтому объяснить пользователю, зачем ему нужен самый современный и производительный процессор  становится всё сложнее и сложнее.

Однако дело даже не в том, что процессор «не загружен» — дело в том, что ни одну «недетскую» задачу современные высокопроизводительные  процессоры в разумный срок решить по-прежнему не способны. Недетскими задачами по-прежнему занимаются суперкомпьютеры и прочие кластеры, в которых одновременно работают не 2 процессора (ядра), и даже не 4, и не 8 — а штук 100 или больше. Дайте 1000-процессорный кластер в руки учёному — он очень быстро найдёт, чем его занять. Дайте 4-ядерную систему в руки домохозяйке — и она будет играть на ней в привычный пасьянс. Природа любит чёрный юмор, поэтому данная ситуация в точности повторяет гораздо более старую: человечество весьма преуспело в лечении ОРЗ, и теперь от этого рода заболеваний можно избавиться уже чуть ли не за сутки — но лейкемия как была неизлечима, так и осталась. Количество увеличивается — но упорно не желает переходить в качество.

Ликуют одни поклонники игр: наконец-таки, появились игрушки, которые задействуют все возможности современных CPU. Правда, никто так толком и не смог выяснить, какое из двух явлений мы наблюдаем: то ли разработчики игр научились использовать возможности 64-битных многоядерных процессоров для того, чтобы сделать свои игры ещё лучше — то ли поддержка 64-битности и многоядерности позволяет выпускать более сырые и неоптимизированные продукты, гордо заявляя о том, что на одноядерной системе в них играть никак нельзя.

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

Например, ОС Microsoft Windows 7 имеет свой встроенный бенчмарк, определяющий условные баллы быстродействия той системы, на который она установлена. При этом тестированию подвергаются несколько основных подсистем компьютера, и результирующий балл представляет собой низший из всех протестированных подсистем. Во многих случаях  низший балл никогда не принадлежал процессору. Зачем, и кому это нужно…

Большинство современных процессорных тестов производительности (бенчмарков), используемых, соответственно, большинством современных независимых тестовых лабораторий, построены на старой предпосылке о том, что  есть Очень Большая Задача, которая занимает Очень Много Времени — и время выполнения данной задачи  Очень Сильно Волнует пользователя. Правда ли это? Да нет же! Сегодня — ничего подобного!

Например: кодирование некоего мультимедийного файла из формата X в формат Y действительно может занимать несколько (ну, хорошо, пусть даже 5-6!) часов — но кто сказал, что это кого-то беспокоит?! Если пользователю срочно захотелось просмотреть (прослушать) содержимое этого файла прямо сейчас — скорее всего, он наплюёт на все эти перекодирования, и запустит файл на просмотр  как он есть.

Он ведь у него уже есть, правда? Кодек не найти? Это смешно... Раз уж потребитель  выкачал этот файл — значит, с интернетом проблем нет. Ну так почему бы не выкачать за 5 минут кодек и не воспроизвести, если невмочь?

Если же он хочет уменьшить его размер, или даже просто привести его к тому формату, который он принял в качестве унифицированного для своей медиа-библиотеки — он запустит процедуру перекодировки… да просто тогда, когда он пойдёт спать (или, наоборот — на работу). И ему будет в достаточно широких временных рамках абсолютно всё равно, сколько данная процедура займёт времени. Учитывая среднестатистическое время сна или работы, разница между 4-мя часами и 6-ю — совершенно не важна, ибо сон всё равно занимает 8, а работа (с учётом дороги туда и обратно) — и того больше.

Поэтому классический, уже изрядно набивший всем оскомину на зубах «бенчмаркинг длительных процессов», по-прежнему традиционно употребляемый в качестве основного метода тестирования производительности всеми независимыми (впрочем, справедливости ради — и «зависимыми» тоже) тестовыми лабораториями — становится чем дальше, тем всё более бессмысленым, неадекватным, и начисто оторванным от реальных нужд рядовых пользователей.

По двум причинам.

Первая из которых: быстродействие современных процессоров и степень оптимизированности кода современных программ, позволяют в подавляющем большинстве случаев избегнуть ситуации, когда время исполнения некоего задания будет настолько долгим, чтобы его было невозможно «вставить» во время вынужденного простоя персонального компьютера. Грубее говоря: целые сутки даже бюджетный процессор никакой навороченный диск Blu-Ray перекодировать не будет.

Вторая причина: получение результата «на кончиках пальцев» (нажал кнопку — через 10 секунд получил результат) — по-прежнему в большинстве сложных случаев невозможно. Ждать придётся, это неизбежно. А час ждать или 20 минут — опять-таки, в большинстве случаев — почти всё равно. То есть, математически, 20 минут — это ровно в 3 раза меньше, чем 1 час, но субъективно — это вполне сопоставимые величины.

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

Переходите на секундомер

«Быстро» сегодня — это синоним «незаметно». Быстродействие современной компьютерной системы — это характеристика не столько даже количественная, сколько качественная. И означает она быстрое исполнение исключительно тех действий, которые в принципе можно (учитывая способности реально существующего   компьютера) выполнить быстро. Сохранение PNG-файла высокого разрешения в Adobe Photoshop в течение 40 секунд реально «напрягает» пользователя в разы больше, чем архивирование всех его документов в течение 2-х часов. Потому что от второго действия он быстроты не ждёт в принципе, а вот 40-секундная пауза при нажатии кнопки «Save» — приводит его в состояние тихого бешенства. Сохранение должно происходить сразу! Немедленно! Он ведь всего лишь хотел сохранить результат своей работы!

Выводы

Оценка производительности компьютеров с помощью специальных тестов  нужна, как по-прежнему нужны весы — только эта оценка тоже постепенно отходит от чугунных гирек к электронным табло.

Обычного  потребителя  не смутит то, что его компьютер не в состоянии отрендерить за 2 часа, а не за 6, сложную сцену в 3ds max. Скорее его смутит то, что после установки антивируса <...> в купе с файрволлом <...>, файлы Word и Excel стали открываться в 3 раза дольше. Можно предположить, что его эта ситуация будет раздражать на порядки больше, чем чисто гипотетическая, когда ему придётся что-то рендерить в 3ds max.

Будущее  оценки производительности компьютеров — за тестированием временной комфортабельности ощущений в процессе работы в привычном (банальном и несложном) ПО, а не за тщательными замерами времени исполнения многочасовых ресурсоёмких процессов. Ресурсоёмкие процессы необходимо оставить тем, для кого они по-прежнему актуальны. Тестировщикам серверов и «навороченных» рабочих станций, например.

Ибо время — это не только часы, минуты, и секунды. Время — это прежде всего реальное, полезное, личное время. Пользователь может его планировать, он вовсе не такой глупый, как кажется. Он может подождать пару часов, когда речь идёт о фоновом процессе (вряд ли он запускает такие процессы каждые 5 минут — потому и может подождать, и вполне к этому готов). Но некоторые результаты своей работы он хочет получать прямо сейчас, сию секунду. Именно этот аспект быстродействия современных компьютерных систем беспокоит его всё чаще и чаще.

Архитектуры RISC и CISC

В 70-х годах прошлого столетия проектирование и изготовление центральных процессоров было занятием, принципиально доступным каждому. Если какому-нибудь сотруднику, скажем, Стэндфордского университета приходила в голову интересная идея, он мог легко набрать команду, основать фирму, найти инвесторов и уже через год-два выбросить на рынок свои процессоры.

Через тридцать с небольшим лет процессоры усложнились до такой степени, что разработка хоть сколько-нибудь быстрого по современным меркам кристалла требует огромной армии инженеров, гигантских инвестиций и целого моря времени. И дело здесь отнюдь не в тонких кремниевых технологиях и стоящих миллиарды долларов полупроводниковых фабриках - просто уже в 80-х годах разработка принципиально нового процессора требовала двух-трех, а в 90-х - пяти-шести лет напряженной работы. Те же китайцы, даже располагая подробной информацией о тридцатилетней истории проектирования процессоров, владея новейшими фабриками по производству кремниевых кристаллов и не стремясь изобретать что-то новое, потратили на разработку собственного простейшего MIPS32-подобного процессора Godson (примерно эквивалентного по производительности i486) несколько лет. Это не считая еще одного года, когда новый кристалл отлаживали. А на разработку MIPS64-подобной архитектуры с приемлемой производительностью (~Pentium III 500–600 МГц) у китайской Академии наук ушло еще четыре года, - четыре года, потраченных только на то, чтобы повторить успех более чем двенадцатилетней давности. Но почему все получается так сложно? Чтобы ответить на этот вопрос  придется вернуться на 30-40 лет в прошлое.

Шаг первый. CISC

Так уж исторически сложилось, что поначалу совершенствование процессоров было направлено на то, чтобы сконструировать по возможности более функциональный компьютер, который позволил бы выполнять как можно больше разных команд. Во-первых, так было удобнее для программистов (компиляторы языков высокого уровня еще только начинали развиваться, и все по-настоящему важные программы писались на ассемблере), а во-вторых, использование сложных команд зачастую позволяло сильно сократить размеры написанной на ассемблере программы. А где меньше команд – меньше и затраченное на исполнение программы время.

Надо признать, что достигнутые на этом пути успехи действительно впечатляли - в последних версиях компьютеров выразительность ассемблерного листинга зачастую не уступала выразительности программы, написанной на языке высокого уровня. Одной-единственной машинной инструкцией можно было сказать практически все, что угодно. К примеру, такие процессора, как DEC VAX, аппаратно поддерживали команды "добавить элемент в очередь", "удалить элемент из очереди" и даже "провести интерполяцию полиномом"; а знаменитое семейство процессоров Motorola 68k почти для всех команд поддерживало до двенадцати  режимов адресации памяти, вплоть до взятия в качестве аргумента команды "данных, записанных по адресу, записанному вон в том регистре, со смещением, записанным вот в этом регистре". Отсюда и общее название соответствующих архитектур: CISC - Complex Instruction Set Computers ("компьютеры с набором команд на все случаи жизни").

На практике это привело к тому, что подобные команды оказалось сложно не только выполнять, но и просто декодировать (выделять из машинного кода новую команду и отправлять ее на исполнительные устройства). Чтобы машинный код CISC-компьютеров из-за сложных команд не разрастался до огромного размера, машинные команды в большинстве этих архитектур имели неоднородную структуру (разное расположение и размеры кода операции и ее операндов) и сильно отличающуюся длину (в x86, например, длина команд варьируется от 1 до 15 байт). Еще одной проблемой стало то, что при сохранении приемлемой сложности процессора многие команды оказалось принципиально невозможно выполнить "чисто аппаратно", и поздние CISC-процессоры были вынуждены обзавестись специальными блоками, которые "на лету" заменяли некоторые сложные команды на последовательности более простых. В результате все CISC-процессоры оказались весьма трудоемкими в проектировании и изготовлении. Но что самое печальное, к моменту расцвета CISC-архитектур стало ясно, что все эти конструкции изобретались в общем-то зря - исследования программного обеспечения того времени, проведенные фирмой IBM, наглядно показали, что даже программисты, пишущие на ассемблере, все эти "сверхвозможности" почти никогда не использовали, а компиляторы языков высокого уровня - и не пытались использовать.

К началу 80-х годов классические CISC архитектуры полностью исчерпали себя. Расширять набор команд в рамках этого подхода дальше не имело смысла, наоборот - технологи столкнулись с тем, что из-за высокой сложности CISC-процессоров оказалось трудно наращивать их тактовую частоту, а из-за "тормознутости" оперативной памяти тех времен зашитые в память процессора расшифровки сложных команд зачастую работают медленнее, чем точно такие же цепочки команд, встречающиеся в основной программе. Короче говоря, стало очевидным, что CISC-процессоры нужно упрощать - и на свет появился RISC, Reduced Instruction Set Computer.

Регистровые окна SPARC

При построении RISC-процессоров принимается во внимание медлительность оперативной памяти. Обращения к ней (даже с учетом различных кэшей) - "дорогостоящи" и требуют дополнительных вычислений, а потому, насколько это возможно, их следует избегать. Но Load/Store-архитектура и большое число регистров - не единственное, что можно сделать.

В любом программе можно встретить немало вызовов функций - фактически требований к процессору перейти в заданное место программы, продолжить выполнение программы до специальной команды возврата, после чего - вернуться к тому месту, где произошел вызов, почти полностью восстановив свое состояние до вызова функции. Чтобы это можно было сделать, при вызове функции процессор должен "запомнить" свое текущее состояние - в частности, содержимое некоторых регистров общего назначения и значительной части специальных регистров. Традиционное решение - "запихнуть" все необходимые данные в специальную конструкцию – стек. Стек можно условно представить как запаянную с одного конца трубку, в которую по одному кладутся и по одному же извлекаются шарики (данные). Первый положенный в трубку шарик извлекается последним, так что если мы, скажем, по очереди положим (push) в стек числа 1, 2, 3, то извлекая (pop) данные, мы поочередно достанем 3, 2, 1.], которую процессор поддерживает на аппаратном уровне и которая в большинстве процессоров реализована в виде пары служебных регистров и выделенного участка оперативной памяти, куда все складываемые в стек данные и записываются. Поэтому любой вызов функции в традиционной схеме неявным образом приводит к записи в оперативную память десятков, а то и сотен байт информации. Есть даже целый ряд модельных задачек на эту тему - как написать компилятор, минимизирующий количество сохраняемой информации; причем кое-какие из этих наработок поддерживаются популярными компиляторами (например, соглашение __fastcall в некоторых компиляторах C/C++). Но оказывается, что всего этого можно избежать.

В типичной SPARC-архитектуре используется регистровый файл из 128 регистров; причем пользователю из них одномоментно доступны только расположенные подряд 24 регистра, образующие в этом файле окно, плюс еще восемь стоящих особняком глобальных регистров. Глобальные регистры используются для глобальных переменных[В структурных языках программирования типа C принято разделять локальные переменные, которые определены и используются только одной конкретной функцией и существуют только то время, пока эта функция работает; и глобальные переменные, которые существуют все время, пока выполняется программа, и доступны всем функциям программы]; регистровое окно - для локальных. Когда нам нужно вызвать какую-нибудь функцию, мы записываем необходимые для ее работы исходные данные в конец окна, а процессор при вызове функции попросту смещает окно по регистровому файлу таким образом, чтобы записанные данные оказались в начале нового, пока пустого окна. Требовавшие сохранения временные данные вызывавшего функцию кода оказываются за пределами окна, так что испортить их нечаянными действиями невозможно. А когда функция заканчивает работу, то полученные результаты записываются в те же самые регистры в начале окна, после чего процессор смещает его обратно. И никаких расходов на сохранение-восстановление стека.

Расположение окон в архитектуре SPARC можно программировать, добиваясь максимально эффективного использования схемы (либо много окон, но маленьких, либо мало - но больших; в зависимости от того, что за функции встречаются в программе) - этот факт даже отражен в названии процессора (Scalable Processor ARChitecture). Подобно многим своим RISC-сестрам, разработанная в середине 80-х годов и пережившая расцвет в середине 90-х, SPARC-архитектура не выдержала "гонки мегагерц" и сегодня фактически умерла. Но предложенный ею подход живет и здравствует - его позволяет использовать, например, архитектура IA-64 (Itanium).

Шаг второй. RISC

Точно так же, как когда-то CISC-процессоры проектировались под нужды ассемблерных программистов, RISC проектировался в расчете на типовой код, генерируемый компиляторами. Для начала разработчики свели к минимуму набор команд и к абсолютному минимуму - количество режимов адресации памяти; упаковав все, что осталось, в простой и удобный для декодирования регулярный машинный код. В частности, в классическом варианте RISC из команд, обращающихся к оперативной памяти, оставлены только две (Load - загрузить данные в регистр и Store - сохранить данные из регистра; так называемая Load/Store-архитектура), и нет ни одной команды вроде вычисления синуса, косинуса или квадратного корня (их можно реализовать "вручную"), не говоря уже о более сложных.(Канонический пример - команда INDEX, выполнявшаяся на VAX медленнее, чем вручную написанный цикл, выполняющий ровно тот же объем работы). Да что там синус с косинусом - в некоторых RISC-процессорах пытались отказаться даже от трудно реализуемого аппаратного умножения и деления! Правда, до таких крайностей ни один коммерческий процессор RISC, к счастью, не дошел, но как минимум две попытки (ранние варианты MIPS и SPARC) предприняты были.

Второе важное усовершенствование RISC-процессоров, целиком вытекающее из Load/Store-архитектуры, - увеличение числа GPR (регистров общего назначения). Варианты, у которых меньше шестнадцати регистров общего назначения  - большая редкость, причем почти все эти регистры полностью равноправны, что позволяет компилятору свободно распоряжаться ими, сохраняя большую часть промежуточных данных именно там, а не в стеке или оперативной памяти. В некоторых архитектурах, типа SPARC, "регистровость" возведена в абсолют, в некоторых - оставлена на разумном уровне; однако почти любой RISC-процессор обладает куда большим набором регистров, чем даже самый продвинутый CISC-процессор. Для сравнения: в классическом x86 IA-32 всего восемь регистров общего назначения, причем каждому из них приписано то или иное "специальное назначение" (скажем, в ESP хранится указатель на стек) затрудняющее или делающее невозможным его использование.

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

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

Условные команды ARM

Архитектура ARM (Advanced RISC Machines) разработана в 1983–85 годах в компании Acorn Computers. Команда Роджера Вильсона и Стива Фербера взяла за основу набора команд ARM некогда популярный, а ныне забытый процессор MOS Technology 6502 и снабдила его специальным четырехбитным кодом условия, которым можно было дополнить любую команду.

Идея условных команд проста, как все гениальное: команда с условным кодом выполняется, только если в процессоре выставлен бит соответствующего условия. В противном случае она игнорируется. Ближайший аналог в наборе команд x86 - команды условного перехода, срабатывающие, только если в процессоре был выставлен тот или иной флаг; в архитектуре ARM подобные "условности" применимы к любой команде, а флаги можно определять самостоятельно. Идея в том, что в коде типа
Если (условие) то Выполнить иначе Выполнить 2
вместо того, чтобы записать традиционную конструкцию:

1 Вычислить условие.
2 Если условие выполнено, то идти к 5.
3 Выполнить  2.
4 Идти к 6.
5 Выполнить 1.
6 …
используя условные команды, можно записать:
1 Вычислить условие и поставить Флаг1 по результатам вычисления.
2 Выполнить1 при условии выставленного Флаг1.
3 Выполнить2 при условии невыставленного Флаг1.

Получившийся код не только более компактен, но и лишен одного условного и одного безусловного перехода, присутствовавших в классическом варианте, - тех самых переходов, которые обычно больно бьют по производительности конвейерных архитектур.

Еще ряд дополнений в архитектуре ARM предусматривал введение команд, одновременно выполняющих несколько простых операций, тем самым избавляя регистры процессора от необходимости сохранять результаты промежуточных вычислений и увеличивая вычислительную плотность программы. Этот подход нетипичен для RISC-процессоров, поскольку плохо вписывается в "основную идею" их максимального упрощения, но в конечном счете он привел к тому, что процессоры Acorn при прочих равных получили большую производительность на единицу частоты. Конечно, ARM-подход тоже имеет недостатки (например, необходимость выполнять пустые команды), однако в общем и целом он позволяет создавать очень простые процессоры с очень хорошей производительностью.

В 1985 вышел первенец архитектуры ARM - 32-разрядный процессор ARM1; в 1986-м - первый коммерческий вариант архитектуры, процессор ARM2. ARM2 был настоящим шедевром - в его ядре насчитывалось всего 30 тысяч транзисторов (вчетверо меньше, чем в процессоре i80286, и втрое меньше, чем в процессоре MC68000); он отличался крайне низким энергопотреблением и обладал при всем при том производительностью, превосходящей производительность 286-го процессора (не говоря уже о том, что 286-й был 16-разрядным, а ARM2 - 32-разрядным процессором). Немного позже увидел свет и ARM3, в котором появилось четыре килобайта кэш-памяти, еще увеличившей производительность процессоров ARM.

Трудно сказать, ожидала ли фирма Acorn Computers такого успеха, однако воспользовалась им в полной мере. В 1990 году Acorn, работавшая над развитием ARM уже в сотрудничестве с Apple, преобразовала подразделение, занимавшееся ARM, в отдельную фирму- Advanced RISC Machines. Результатом совместной работы стало ядро ARM6 и процессор ARM610, использовавшийся, в частности, в одном из первых КПК в мире - Apple Newton. Ядро ARM6 было по-прежнему невероятно простым (всего 35 тысяч транзисторов!), мало потребляющим и обеспечивало приличный уровень производительности. Поскольку тягаться в производительности с гораздо более сложными монстрами вроде процессора i386 оно не могло (да и ниша высокопроизводительных вычислений была прочно занята MIPS), руководство Advanced RISC Machines избрало оригинальный способ ведения бизнеса - позиционировав ARM6 как "встраиваемое" вычислительное ядро, которое любой желающий за сравнительно небольшие деньги мог интегрировать в свои специализированные процессоры. Ядро ARM6 вышло столь удачным и так хорошо подходило для этой бизнес-модели (благодаря простоте, его можно было изготавливать даже на сильно устаревшем дешевом оборудовании), что вскоре архитектура ARM получила широчайшее распространение. Самый яркий пример подобного "гибрида" - ядро ARM7TDMI, являвшегося основой для подавляющего большинства процессоров сотовых телефонов. Сегодня ARM используется в более чем 75% всех интегрированных процессоров, выпускаемых в мире, - от контроллеров жестких дисков, калькуляторов и микропроцессоров игрушек до сетевых маршрутизаторов. То есть там, где от процессора не требуется очень высокого быстродействия.

Шаг 3. Введение конвейера

Идея конвейера, давным-давно предложенная Генри Фордом, состоит в том, что производительность цепочки последовательных действий определяется не сложностью этой цепочки, а лишь длительностью самой сложной операции. Иными словами, совершенно неважно, сколько человек занимаются производством автомобиля и как долго длится его изготовление в целом, - важно то, что если каждый человек в цепочке тратит, скажем, на свою операцию одну минуту, то с конвейера будет сходить один автомобиль в минуту, ни больше и ни меньше; независимо от того, сколько операций нужно совершить с отдельным автомобилем и сколько заняла бы его сборка одним человеком. Применительно к процессорам принцип конвейера означает, что если мы сумеем разбить выполнение машинной команды на несколько этапов, то тактовая частота (а вернее, скорость, с которой процессор забирает данные на исполнение и выдает результаты) будет обратно пропорциональна времени выполнения самого медленного этапа. Если это время удастся сделать достаточно малым (а чем больше этапов на конвейере, тем они короче), то мы сумеем резко повысить тактовую частоту, а значит, и производительность процессора.

Процедуру выполнения практически любой команды можно разбить как минимум на пять непересекающихся этапов:

  1.  Выборка команды (FETCH) из памяти. Из программы извлекается команда, которую нужно выполнить.
  2.  Декодирование команды (DECODE). Процессор "соображает", что от него хотят, и переправляет запрос на нужное исполнительное устройство.
  3.  Подготовка исходных данных для выполнения команды.
  4.  Собственно выполнение команды (EXECUTE).
  5.  Сохранение полученных результатов.

Конвейеризация потенциально применима к любой процессорной архитектуре, независимо от набора команд и положенных в ее основу принципов. Даже самый первый x86-процессор, Intel 8086, уже содержал своеобразный примитивный "двухстадийный конвейер" - выборка новых команд (FETCH) и их исполнение осуществлялись в нем независимо друг от друга. Однако реализовать что-то более сложное для CISC-процессоров оказалось трудно: декодирование неоднородных CISC-команд и их очень сильно различающаяся сложность привели к тому, что конвейер получается чересчур замысловатым, катастрофически усложняя процессор. Подобных трудностей у RISC-архитектуры гораздо меньше (а SPARC и MIPS, например, и вовсе были специально оптимизированы для конвейеризации), так что конвейеризированные RISC-процессоры появились на рынке много раньше, чем аналогичные x86.

Недостатки конвейера неочевидны, но, как обычно и бывает, из-за нескольких "мелочей" реализовать грамотно организованный конвейер совсем не просто. Основных проблем три.

  1.  Необходимость наличия блокировок конвейера. Дело в том, что время исполнения большинства команд может очень сильно варьироваться. Скажем, умножение (и тем более деление) чисел требуют (на стадии EXECUTE) нескольких тактов, а сложение или побитовые операции - одного такта; а для операций Load и Store, которые могут обращаться к разным уровням кэш-памяти или к оперативной памяти, это время вообще не определено (и может достигать сотен тактов). Соответственно, должен быть какой-то механизм, который бы "притормаживал" выборку и декодирование новых команд до тех пор, пока не будут завершены старые. Методов решения этой проблемы много, но их развитие приводит к одному - в процессорах прямо перед исполнительными устройствами появляются специальные блоки-диспетчеры (dispatcher), которые накапливают подготовленные к исполнению команды, отслеживают выполнение ранее запущенных команд и по мере освобождения исполнительных устройств отправляют на них новые команды. Даже если исполнение займет много тактов - внутренняя очередь диспетчера позволит в большинстве случаев не останавливать подготавливающий все новые и новые команды конвейер (Новые команды тоже не каждый такт удается декодировать, так что возможна и обратная ситуация: новых команд за такт не появилось, и диспетчер отправляет команды на выполнение "из старых запасов"). Так в процессоре возникает разделение на две независимо работающие подсистемы: Front-end (блоки, занимающиеся декодированием команд и их подготовкой к исполнению) и Back-end (блоки, собственно исполняющие команды).
  2.  Необходимость наличия системы сброса процессора. Поскольку операции FETCH и EXECUTE всегда выделены в отдельные стадии конвейера, то в тех случаях, когда в программе происходит разветвление (условный переход), зачастую оказывается, что по какой из веток пойти - пока неизвестно: команда, вычисляющая код условия, еще не выполнена. (Вот здесь-то и нужны те самые режимы выставления флагов архитектуры PowerPC). В результате процессор вынужден либо приостанавливать выборку новых команд до тех пор, пока не будет вычислен код условия (а это может занять очень много времени и в типичном цикле страшно затормозит процессор), либо, руководствуясь соображениями блока предсказания переходов, "угадывать", какой из переходов скорее всего окажется правильным.
  3.  Наконец, конвейер обычно требует наличия специального планировщика (scheduler), призванного решать конфликты по данным. Если в программе идет зависимая цепочка команд (когда команда-2, следующая за инструкцией-1, использует для своих вычислений данные, только что вычисленные инструкцией-1), а время исполнения одной команды (от момента запуска на стадию EXECUTE и до записи полученных результатов в регистры) превосходит один такт, то мы вынуждены придержать выполнение очередной команды до тех пор, пока не будет полностью выполнена ее предшественница. К примеру, если мы вычисляем выражение вида A•B+C с сохранением результата в переменной X (XfA•B+C), то процессор, выполняя соответствующую выражению цепочку из двух команд типа R4fR1•R2; R0fR3+R4, должен вначале дождаться, пока первая команда сохранит результат умножения A•B, и только потом прибавлять к полученному результату число С. Цепочки зависимых команд в программах - скорее правило, нежели исключение, а исполнение команды с записью результата в регистры за один такт - наоборот, скорее исключение, нежели правило, поэтому в той или иной степени с проблемой зависимости по данным любая конвейерная архитектура обязательно сталкивается. Оттого-то в конвейере и появляются сложные декодеры, заранее выявляющие эти зависимости, и планировщики, которые запускают команды на исполнение, выдерживая паузу между запуском главной команды и зависимой от нее.

Идея конвейера в процессоре очень красива на словах и в теории, однако реализовать ее даже в простом варианте чрезвычайно трудно. Но выгода от конвейеризации столь велика и несомненна, что приходится с этими трудностями мириться, ведь ничего лучшего до сих пор не придумано.

В 1991–92 годах фирма Intel, освоив производство сложнейших кристаллов с более чем миллионом транзисторов, выпустила процессор i486 - классический CISC-процессор архитектуры x86, но с пятистадийным конвейером. Чтобы оценить этот рывок, приведем две цифры: тактовую частоту по сравнению с процессором i386 введение конвейера позволило увеличить втрое, а производительность на единицу частоты – вдвое (В процессоре i386 многие команды выполнялись за несколько тактов; а в процессоре i486 среднее "время" исполнения команды в тактах удалось снизить почти вдвое). Правда, расплатой за это стала чудовищная сложность ядра процессора i486; но такие "мелочи" по меркам индустрии центральных процессоров - пустяк: быстро растущие технологические возможности кремниевой технологии уже через пару лет позволили освоить производство процессора i486 всем желающим. Но к тому моменту RISC-архитектуры сделали еще один шаг вперед - к суперскалярным процессорам.

Шаг 4. Суперскалярные и Out-of-Order-процессоры

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

Запускать на исполняющие устройства сразу несколько команд (если они не зависят друг от друга и могут быть безболезненно выполнены одновременно).

Переупорядочивать независящие друг от друга команды так, как сочтем нужным.

Процессоры, использующие первую технику, называются суперскалярными. К примеру, сугубо теоретически, по числу исполнительных устройств, процессор Pentium 4 мог выполнять семь команд за такт, а процессор Athlon 64 - девять. Реальные цифры, конечно, гораздо скромнее и определяются трудностью полноценной загрузки всех исполнительных устройств, однако процессор Pentium 4 все же способен исполнять в устоявшемся режиме две (при некоторых условиях - четыре), а процессор Athlon 64 - три команды за такт, одновременно производя две (A64 - три) операции по адресации и выборке данных из оперативной памяти. Может показаться, что реализация суперскалярного процессора очень проста (достаточно со стадии schedule просто распределять команды по разным исполнительным устройствам), однако такой лобовой подход обычно упирается в то, что Front-end процессора перестает успевать загружать исполнительные блоки работой. Поэтому на практике хорошо сделанные суперскалярные архитектуры, подобные структурам K7/K8 фирмы AMD, приходится специально "затачивать" под суперскалярность.

Процессоры, использующие вторую технику, называются процессорами с внеочередным исполнением команд (Out-of-Order processors, OoO). Техника переупорядочивания команд замечательна тем, что резко ослабляет негативные эффекты от медленной оперативной памяти и от наличия зависимых цепочек команд. Если, например, команда A обратилась к оперативной памяти, а нужных данных в кэше не оказалось или если A занимается ожиданием результатов выполнения какой-то другой команды, то OoO-процессор сможет пропустить вперед другие команды, не зависящие от результатов выполнения команды A. Кроме того, продвинутый планировщик OoO-процессора иногда может использоваться для реализации специфических деталей той или иной архитектуры - например, для спекулятивного исполнения по данным в случае процессора Pentium 4 или одновременного исполнения нескольких веток программы в архитектуре IA-64. Реализация OoO-процессоров не требует специальной оптимизации всего конвейера - это всего лишь усложнение схемы планировщиков, запускающих готовые к исполнению команды на исполнительные устройства в другом порядке, нежели они на планировщики поступили, плюс усложнение схем сброса конвейера и сохранения полученных результатов: результат выполнения прошедших вне очереди команд все равно должен сохраняться в последовательности, строго соответствующей расположению команд в изначальном коде. (Это связано с тем, что если случится какая-то ошибка, то результаты выполнения запущенных вперед очереди команды придется аннулировать).

На сегодняшний день не существует ни одного суперскалярного или OoO CISC-процессора. Дело в том, что поскольку для нормальной реализации навороченных диспетчеров и планировщиков все равно требуется длительная и тщательная подготовка команд, причем желательно - до такого простого состояния, чтобы эти функционирующие на огромных частотах модули особенно не "задумывались" над тем, что такая хитрая последовательность байтов означает и куда ее следует направить (проблем у них и без того хватает), то любой исходный машинный код Front-end процессоров превращает перед исполнением в некое внутреннее, упрощенное и "разжеванное", состояние. То есть на этом этапе развития различия между RISC- и CISC-архитектурами почти стираются - просто у RISC-процессоров декодер, превращающий исходный машинные команды в содержимое очередей планировщиков, устроен гораздо проще, чем "расковыривающий" хитро упакованные x86-команды CISC-подобный декодер процессоров Athlon и  Pentium. Так что можно сказать, что фактически все современные x86-процессоры "в глубине души" являются полноценными RISC-процессорами - ведь исходные x86-программы они в любом случае преобразуют на лету во внутреннее RISC-подобное представление. Правда, разной сложностью декодеров дело не ограничивается: все-таки классическую RISC-программу не только проще преобразовывать, но и результирующая  внутренняя программа  из него получается лучше - планировщикам гораздо легче его обрабатывать (в нем меньше зависимостей и операций с оперативной памятью). Вот и появляются в архитектуре  x86 все новые и новые расширенные наборы команд (от 3Dnow! до SSE всех версий иAVX).

Блок предсказания переходов


Да-да, именно так называется этот странный блок! Но "гадание на кофейной гуще" здесь ни при чем - переходы предсказываются на основе вполне научных соображений. Обычно используется очень простой способ: в процессоре ведется таблица ранее совершенных переходов - для каждого условного перехода подсчитывается, сколько раз он "сработал", а сколько - "был проигнорирован". Поэтому, скажем, когда процессор встречает переход, замыкающий какой-нибудь цикл, то он быстренько начинает считать: раз переход сработал, два сработал, три сработал - ну, значит, наверное, он всегда будет срабатывать, вот так и будем предсказывать, что переход всегда происходит. То, что мы один раз в конце цикла ошибемся, - не беда, зато ценой максимум двух ошибок мы добьемся точного предсказания во всех остальных случаях. Кстати, на простых циклах процессор, как правило, ошибается еще реже - не более одного раза: по умолчанию, когда не из чего выбирать, считается, что условный переход всегда происходит.

При неправильном предсказании конвейер обычно приходится "сбрасывать", каким-то образом восстанавливая состояние процессора, предшествующее моменту неправильного перехода. А ведь пока исполнялась неправильная ветка, там ого-го сколько всего могло случиться! Неправильный код операции (нераспознаваемая машинная команда), обращение к виртуальной памяти (провоцирующее исключение в процессоре), некстати распознанное деление на ноль (тоже ошибка). Все это приходится тщательно отслеживать и проверять, причем это не шутки: одно время из-за ошибки в реализации конвейера процессора AMD K5, программист, написавший конструкцию если x A 0, то y = 1/x, иначе y = 0, запросто мог получить при x @ 0 на, казалось бы, ровном месте ошибку "деление на ноль", вызванную неправильным предсказанием перехода. А в OoO-процессорах ситуация еще сложнее - пока "тормозит" не вовремя отправившаяся за операндами в оперативную память команда, процессор успевает пропустить вперед, выполнить и едва ли не сохранить результат вычисления десятков команд неправильной ветки: попробуй за всем этим уследить!

Но бороться здесь есть за что: для современных процессоров каждая ошибка предсказания - это десятки вхолостую израсходованных тактов. Сущая катастрофа, если учитывать, что за каждый такт можно было бы исполнить до 3-4 x86-команд и совершить кучу вычислений. Если бы блока предсказания не было, то так "тормозил" бы каждый условный переход.

Точность предсказания современных блоков составляет на тестах SPEC порядка 98–99%. Может показаться, что совершенствовать блок не имеет смысла, но это не совсем так. Дело в том, что на производительности гораздо больше сказывается процент ошибок, а не верных предсказаний. А переход от 98-процентной точности к 99-процентной означает двукратное снижение ошибок - с 2% до 1%! Поэтому если вы внимательно почитаете пресс-релизы о новых процессорах, то заметите, что "усовершенствованный блок предсказания переходов" упоминается в них почти всегда.

В архитектуре IA-64 техника предсказания переходов сделала значительный шаг вперед - эти процессоры умеют одновременно вычислять несколько веток программного кода. То есть, встретив команду условного перехода, процессор начинает "охотиться за двумя зайцами" - просчитывать оба варианта развития событий вплоть до того момента, пока не станет ясно, какой из них правильный. Поскольку команды "разных вариантов" практически не зависят друг от друга, а исполнительные устройства процессоров Itanium обычно загружены далеко не полностью, то исполнять побочную ветку нередко удается практически с той же скоростью, что и основную, так что даже при неправильном предсказании условного перехода происходит не остановка процессора на пару десятков тактов, а всего лишь снижение производительности на небольшом участке кода.

Архитектура PowerPC

Последняя из ныне здравствующих процессорных RISC-архитектур - это, конечно же, знаменитая PowerPC, детище альянса Apple, IBM и Motorola (AIM). Сегодня на PowerPC есть четкие спецификации, следуя которым любой желающий может разработать совместимый с ним процессор. Ничего особо интересного в нем нет - это самый что ни на есть классический RISC-процессор без специальных "примочек". Существуют 32- и 64-разрядные версии PowerPC (причем 64-разрядные совместимы с 32-разрядным кодом), а равно и ряд стандартизованных расширений (типа эппловского набора команд AltiVec). В то время как MIPS и ARM "специализировались" на тех или иных применениях, PowerPC, подобно x86, позиционировалась в основном для обычных персоналок и серверов. Вплоть до 2001 года x86 и PowerPC развивались более или менее синхронно, однако из-за технологических проблем и неспособности угнаться за процессорами AMD и Intel в "гонке мегагерц" PPC шаг за шагом сдавала позиции. А исчерпав "запас прочности" и застряв на частотах 1,0–1,4 ГГц, она стала стремительно проигрывать архитектуре x86, по-прежнему сохранявшей высокие темпы развития из-за ожесточенной схватки Intel и AMD. Поскольку "отступать" PowerPC было в общем-то некуда (нишу интегрированных процессоров оккупировали ARM и MIPS), то многие посчитали ее верным кандидатом на вымирание. Даже Apple недавно "отреклась" от своей архитектуры, переметнувшись в стан приверженцев x86. Только крайне дорогие серверные процессоры POWER, выпускавшиеся на пределе технологических возможностей Голубого гиганта (Power4, в частности, стали первыми в мире двухъядерниками), еще довольно уверенно чувствуют себя в линейке продуктов IBM.

Однако ситуация, похоже, начала меняться: именно архитектура PowerPC положена в основу будущих многоядерных процессоров всех игровых приставок шестого поколения (от Sony, Microsoft и Nintendo), поскольку ни MIPS, ни тем более ARM на эту роль не годятся; процессоры Intel в их текущем варианте плохо подходят для создания игровых приставок нового поколения; о процессорах AMD и говорить не приходится - компания просто не в состоянии обеспечить достаточный объем их производства. Вот и остается единственным кандидатом на роль нового "суперпроцессора" только всем доступная, технологически более простая, нежели x86, и достаточно производительная архитектура PowerPC. Что еще важнее для PPC, именно она положена в качестве аппаратной основы концепции Cell, которая, возможно, станет следующим шагом в развитии компьютинга. Так что пожелаем РРС удачи - от наличия на рынке множества альтернатив пользователи только выигрывают, и видеть в обозримом будущем абсолютную монополию x86, даже в варианте AMD64, не хотелось бы.

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

В фирме IBM этой тенденции противостояла группа разработчиков во главе с Джоном Коком; они попытались воплотить идеи Сеймура Крея, создав экспериментальный высокоэффективный мини-компьютер IBM 801. Хотя фирма IBM не занималась сбытом этой процессора, а результаты эксперимента были опубликованы только через несколько лет, весть быстро разнеслась по свету, и другие производители тоже занялись разработкой подобных архитектур.

В 1980 году группа разработчиков в университете Беркли во главе с Дэвидом Паттерсоном  и Карло Секвином   начала разработку не ориентированных на интерпретацию процессоров VLSI. Для обозначения этого понятия они придумали термин RISC, а новый процессор назвали RISC I, вслед за которым вскоре был выпущен RISC II. Немного позже, в 1981 году, Джон Хеннеси в Стенфорде разработал и выпустил другую микросхему, которую он назвал MIPS. Эти две микросхемы развились в коммерчески важные продукты  SPARC и MIPS, соответственно.

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

В то время, когда разрабатывались эти простые процессоры, всеобщее внимание привлекало относительно небольшое количество команд (обычно около 50). Для сравнения: число команд в компьютерах VAX производства фирмы DEC и больших компьютерах производства фирмы IBM в то время составляло от 200 до 300. Компьютер RISC (Reduced Instruction Set Computer — компьютер с сокращенным набором команд) противопоставлялся системе CISC (Complex Instruction Set Computer — компьютер с полным набором команд). В качестве примера процессора типа CISC можно привести компьютер VAX, который доминировал в то время в университетской среде. На сегодняшний день мало кто считает, что главное отличие RISC и CISC состоит в количестве команд, но названия сохраняются до сих пор.

С этого момента началась грандиозная идеологическая война между сторонниками RISC и разработчиками больших вычислительных систем фирм DEC, Intel и  IBM. По мнению первых, наилучший способ разработки компьютеров — включение туда небольшого количества простых команд, каждая из которых выполняется за один цикл тракта данных (см. рис. 2.2), то есть производит над парой регистров какую-либо арифметическую или логическую операцию (например, сложение или операцию логического И) и помещает результат обратно в регистр. В качестве аргумента они утверждали, что, даже если системе RISC приходится выполнять 4 или 5 команд вместо одной, которую выполняет CISC, RISC все равно выигрывает в скорости, так как RISC-команды выполняются в 10 раз быстрее (поскольку они не интерпретируются). Следует также отметить, что к этому времени быстродействие основной памяти приблизилось к быстродействию специальных командных ПЗУ, поэтому недостатки интерпретации были налицо, что еще более поднимало популярность компьютеров RISC.

Учитывая преимущества RISC в плане производительности, можно было предположить, что на рынке такие компьютеры, как Alpha фирмы DEC, должны доминировать над компьютерами CISC (Pentium и т. д.). Однако ничего подобного не произошло. Возникает вопрос: почему?

Во-первых, компьютеры RISC несовместимы с другими моделями, а многие фирмы вложили миллиарды долларов в программное обеспечение для продукции Intel. Во-вторых, как ни странно, фирма Intel сумела воплотить те же идеи в архитектуре CISC. Процессоры фирмы Intel, начиная с процессора 486, содержат RISC-ядро, которое выполняет самые простые (и обычно самые распространенные) команды за один цикл тракта данных, а по обычной технологии CISC интерпретируются более сложные команды. В результате обычные команды выполняются быстро, а более сложные и редкие — медленно. Хотя при таком “гибридном” подходе производительность ниже, чем в архитектуре RISC, новая архитектура CISC имеет ряд преимуществ, поскольку позволяет использовать старое программное обеспечение без изменений.

Основные принципы разработки современных компьютеров

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

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

Все команды должны выполняться непосредственно аппаратным обеспечением. То есть обычные команды не интерпретируются микрокомандами. Устранение уровня интерпретации повышает скорость выполнения большинства команд. В компьютерах с архитектурой  CISC более сложные команды могут разбиваться на несколько шагов, которые затем выполняются как последовательность микрокоманд. Эта дополнительная операция снижает быстродействие процессора, но может использоваться для редко применяемых команд.

Компьютер должен запускать как можно больше команд в секунду. В современных компьютерах используется много различных способов повышения производительности, главный из которых — запуск как можно большего количества команд в секунду. Современные процессоры  способены запускать миллиарды  команд в секунду, и при этом не имеет значения, сколько времени занимает выполнение этих команд. (MIPS — это сокращение от Millions of Instructions Per Second — миллионы команд в секунду.) Этот принцип предполагает, что параллелизм должен играть главную роль в повышении производительности, поскольку запустить на выполнение большое количество команд за короткий промежуток времени можно только в том случае, если есть возможность одновременного выполнения нескольких команд.

Хотя команды любой программы всегда располагаются в оперативной памяти в определенном порядке, компьютер способен изменить порядок их запуска (так как необходимые ресурсы памяти могут быть заняты) и (или) завершения. Конечно, если команда 1 устанавливает значение в регистр, а команда 2 использует этот регистр, нужно действовать с особой осторожностью, чтобы команда 2 не считала значение из регистра раньше, чем оно там окажется. Чтобы не допускать подобных ошибок, необходимо хранить в памяти большое количество дополнительной информации, но благодаря возможности выполнять несколько команд одновременно производительность все равно оказывается выше.

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

К памяти должны обращаться только команды загрузки и сохранения. Один из самых простых способов разбить операцию на отдельные шаги — сделать так, чтобы операнды большей части команд брались из регистров и возвращались туда же. Операция перемещения операндов из памяти в регистры и обратно может осуществляться в разных командах. Поскольку доступ к памяти занимает много времени, причем длительность задержки не поддается прогнозированию, выполнение этих команд могут взять на себя другие команды, единственное назначение которых — перемещение операндов между регистрами и памятью. То есть к памяти должны обращаться только команды загрузки и сохранения (LOAD и STORE).

Регистров должно быть много. Поскольку доступ к памяти происходит довольно медленно, в компьютере должно быть много регистров (по крайней мере, 32). Если слово однажды вызвано из памяти, при наличии большого числа регистров оно может содержаться в регистре до тех пор, пока не потребуется. Возвращение слова из регистра в память и новая загрузка этого же слова в регистр нежелательны. Лучший способ избежать излишних перемещений — наличие достаточного количества регистров.

Особенности архитектуры  ARM

Название ARM происходит от "Advanced RISC Machines". Следует заметить, что фирма ARM специализируется сугубо на разработке процессорных ядер и периферийных блоков, при этом, не имеет производственных мощностей по выпуску микросхем. Фирма  ARM поставляет свои разработки в электронной форме, на основе которой клиенты конструируют свои собственные микросхемы (процессоры, микроконтроллеры, системы на кристалле). Клиентами компании являются свыше 60 компаний-производителей полупроводников, среди которых можно выделить таких популярных производителей, как Altera, Analog Devices, Atmel, Cirrus Logic, Fujitsu, MagnaChip (Hynix), Intel, Motorola, National Semiconductor, Philips, ST Microelectronics и Texas Instruments.

Краткая история продуктов фирмы ARM

В одном из первых ядер, а именно в ядре ARM2 были реализованы: 32-разрядная шина данных; 26-битное адресное пространство; 16 32-разрядных регистров. Программный код должен был лежать в первых 64 мегабайтах памяти, а программный счетчик был ограничен 26 битами, так как верхние 4 и нижние 2 бита 32-битного регистра служили флагами.

Ядро ARM2 стало, возможно, самым простым из полезных 32-битных процессоров в мире, имея всего лишь 30000 транзисторов (для сравнения, в сделанном на 6 лет раньше процессоре Motorola 68000 было около 70000 транзисторов). Многое из этой простоты обусловлено отсутствием микрокода (который в процессоре 68000 занимал от одной четверти до одной трети), и отсутствием кэша, как и в многих процессорах того времени. Эта простота привела к низким затратам энергии, в то время как ядро ARM был гораздо более производителенее, чем даже процессор Intel 80286. У его преемника — ядра ARM3 — кэш был уже 4 Кбайт, что еще сильнее увеличило производительность.

Ядро ARM сохранило все тот же размер после всех этих изменений. У ядра ARM2 было 30000 транзисторов, в то время как ядро ARM6 доросло всего лишь до 35000.

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

Под лицензией фирмы ARM в 2005 году было произведено около 1,6 миллиардов ядер ARM, из них около миллиарда ядер ARM пошло на мобильные телефоны. По состоянию на январь 2008 года было произведено более 10 миллиардов ядер, а по прогнозу в 2011 году их будет производиться 5 миллиардов ядер ежегодно.

Архитектура, которую поддерживают смартфоны, карманные персональные компьютеры и другие портативные устройства — это 5 версия (ARMv5). Процессоры с ядрами   XScale и ARM926 (ARMv5TE)  более многочисленны в высокотехничных устройствах, чем, например, процессоры  StrongARM и процессоры ARMv4 на базе ARM9TDMI и ARM7TDMI, но менее сложные приборы могут использовать старые версии с меньшей лицензионной стоимостью. Процессоры с архитектурой ARMv6 (версия 6) по своей производительности на голову выше, чем стандартные процессоры с ядрами архитектуры ARMv5, и используются в некоторых случаях.

Процессоры Cortex с архитектурой ARMv7  (весия 7)  показывают большую производительность и экономичность, чем все предыдущие поколения.

Процессоры Cortex-A предназначены  специально для смартфонов,  в которых раньше использовали процессоры с архитектурами ARM9 и ARM11.

Процессоры Cortex-R  предназначены  для приложений, работающих в реальном времени, а процессоры Cortex-M — для микроконтроллеров.

В настоящее время архитектура ARM занимает лидирующие позиции и охватывает болшую часть рынка гаджетов и встраиваемых RISC-микроконтроллеров. Распространенность данного ядра объясняется его стандартностью, что предоставляет возможность разработчику более гибко использовать, как свои, так и сторонние программные наработки, как при переходе на новое процессорное ARM-ядро, так и при миграциях между разными типами ARM-микроконтроллеров.

Архитектура

Версии архитектуры ARM:

  •  ARMv1: ARM1
  •  ARMv2: ARM2, ARM3
  •  ARMv3: ARM6, ARM7
  •  ARMv4: StrongARM, ARM7TDMI, ARM9TDMI
  •  ARMv5: ARM7EJ, ARM9E, ARM10E, XScale
  •  ARMv6: ARM11
  •  ARMv7: Cortex

Рис. 1. Версии архитектуры ARM.

Процессоры архитектуры ARMv5 и ARMv4 до сих пор используются в не очень сложных устройствах, так как позволяют обойтись меньшими затратами за лицензии. Процессоры ARMv6 значительно производительнее.

Процессоры семейства ARMv7, также известны как Cortex. Они отличаются ещё большей скоростью и энергоэффективностью и делятся на подвиды: Cortex-A применяется в смартфонах, Cortex-R созданы для приложений реального времени, а Cortex-M — для микроконтроллеров. Вот как они отличаются по возможностям и производительности (схематично).

Рис. 2.

Набор команд

В архитектуре ARM реализованы следующие особенности RISC-архитектур:

  •  Все команды 32-х разрядные;
  •  Команды обращения в память выделены в отдельную группу;
  •  Команды обработки оперируют с содержимым только регистров;
  •  Предусмотрено 16 32-х разрядных регистров общего назначения;
  •  Реализовано условное выполнение команд;
  •  Мощные индексированные адресные режимы;
  •  Простые, но быстрые, с двумя уровнями приоритетов подсистемы прерываний с включенными банками регистров;
  •  Возможность расширения системы команд командами сопроцессоров.

Условное высполнение

Одним из существенных отличий архитектуры ARM от других архитектур  является так называемая предикация - возможность условного исполнения команд. Под "условным исполнением" здесь понимается то, что команда будет выполнена или проигнорирована в зависимости от текущего состояния флагов состояния процессора.

В то время как для других архитектур таким свойством, как правило, обладают только команды условных переходов, в архитектуру ARM была заложена возможность условного исполнения практически любой команды. Это было достигнуто добавлением в коды их инструкций особого 4-битового поля (предиката). Одно из его значений зарезервировано  на то, что инструкция должна быть выполнена безусловно, а остальные кодируют то или иное сочетание условий (флагов). С одной стороны, с учётом ограниченности общей длины инструкции, это сократило число бит, доступных для кодирования смещения в командах обращения к памяти, но с другой - позволило избавляться от инструкций ветвления при генерации кода для небольших if-блоков.

Пример, обычно рассматриваемый для иллюстрации — основанный на делении алгоритм Евклида. В языке C он выглядит так:

   while (i != j)

   {

      if (i > j)

          i -= j;

      else

          j -= i;

   }

А на ассемблере ARM — так:

loop CMP Ri, Rj; set condition «NE» if (i != j),

                           ;               "GT" if (i > j),

                           ;            or "LT" if (i < j)

       SUBGT  Ri, Ri, Rj   ; if "GT" (greater than), i = i-j;

       SUBLT  Rj, Rj, Ri   ; if "LT" (less than), j = j-i;

       BNE    loop         ; if "NE" (not equal), then loop

Из кода видно, что использование предикации позволило полностью избежать ветвления в операторах else и then. Заметим, что если Ri и Rj равны, то ни одна из SUB инструкций не будет выполнена, полностью убирая необходимость в ветке, реализующей проверку while при каждом начале цикла, что могло быть реализовано, например, при помощи инструкции SUBLE (меньше либо равно).

Один из способов, которым уплотнённый (Thumb) код достигает большей экономии объёма — это именно удаление 4-битового предиката из всех инструкций, кроме ветвлений.

Другие особенности

Другая особенность набора команд это возможность соединять сдвиги и вращения в инструкции «обработки информации» (арифметическую, логическую, движение регистр-регистр) так, что, например выражение С:

a += (j << 2);

может быть преобразовано в команду из одного слова и одного цикла в ARM:

ADD Ra, Ra, Rj, LSL #2

Это приводит к тому, что типичные программы ARM становятся плотнее, чем обычно, с меньшим доступом к памяти. Таким образом, конвейер используется гораздо более эффективно. Даже несмотря на то, что ARM работает на скоростях, которые многие бы сочли низкими, он довольно-таки легко конкурирует с многими более сложными архитектурами ЦПУ.

Конвейер и другие аспекты реализации

ARM7 и более ранние версии имели трехступенчатый конвейер. Это ступени выбора команды, декодирования и исполнения. Более производительные архитектуры, типа ARM9, имеют более сложные конвейеры. Например, Cortex-А8 имеет 13-ступенчатый конвейер.

Сопроцессоры

Архитектура предоставляет способ расширения набора команд, используя сопроцессоры, которые могут быть адресованы, используя MCR, MRC, MRRC, MCRR и похожие команды. Пространство сопроцессора логически разбито на 16 сопроцессоров с номерами от 0 до 15, причем 15-й зарезервирован для некоторых типичных функций управления, типа управления кэш-памятью и MMUоперации (на процессорах, в которых они есть).

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

Thumb

Для улучшения компилируемой плотности кода, процессоры, начиная с ARM7TDMI, снабжены режимом Thumb. В этом режиме процессор выполняет 16-разрядные команды. Большинство из этих 16-разрядных команд Thumb переводятся в нормальные команды ARM. Экономия пространства происходит за счет сокрытия некоторых операндов и ограничения возможностей по сравнению с режимом полного набора команд ARM.

В режиме Thumb меньшие коды операций обладают меньшей функциональностью. Например, только ветвления могут быть условными, и многие коды операций имеют ограничение на доступ только к половине главных регистров процессора. Более короткие коды операций в целом дают большую плотность кода, хотя некоторые операции требуют дополнительных команд. В ситуациях, когда порт памяти или ширина шины ограничены 32мя битами, более короткие коды операций режима тумбы становятся гораздо производительнее по сравнению с обычным 32-битным ARM кодом, так как меньший программный код придется загружать в процессор при ограниченной пропускной способности памяти.

Первым процессором с декодером  команд Thumb был ARM7TDMI. Все процессоры семейства ARM9, а также XScale, имели встроенный декодер тумбовых команд.

Thumb-2

Thumb-2 — технология, стартовавшая с ядра ARM1156, анонсированного в 2003 году. Он расширяет ограниченный 16-битный набор команд Thumb дополнительными 32-битными командами, чтобы задать набору команд дополнительную ширину. Цель архитектуры Thumb-2 — достичь плотности кода как у Thumb, и производительности как у набора команд ARM на 32 битах. Можно сказать, что в архитектуре ARMv7 эта цель была достигнута.

Thumb-2 расширяет как команды ARM, так и команды Thumb еще большим количеством команд, включая управление битовым полем, табличное ветвление, условное исполнение. Новый язык «Unified Assembly Language» (UAL) поддерживает создание команд как для ARM, так и для Thumb из одного и того же исходного кода. Версии Thumb на ARMv7 выглядят как код ARM.

Все микросхемы с ядрами  ARMv7 поддерживают набор команд Thumb-2, а некоторые микросхемы, вроде Cortex-M3, поддерживают только Thumb-2. Остальные микросхемы  Cortex и ARM11 поддерживают наборы команд как Thumb-2, так и ARM.

Jazelle

Jazelle — это метод, который позволяет байт-коду Java исполняться прямо в архитектуре ARM в качестве 3го состояния исполнения (и набора команд) наряду с обычными командами ARM и режимом бегунка. Поддержка этого свойства обозначается буквой «J» в названии процессора — например, ARMv5TEJ. Необходимость такой поддержки появляется начиная с процессоров ARMv6, хотя новые ядра лишь содержат тривиальные реализации, которые не поддерживают аппаратного ускорения.

Технология SIMD

Технология SIMD (несколько данных в одной инструкции) используется в media-расширении и нацелена на увеличение скорости обработки данных в приложениях, где требуется малое энергопотребление. SIMD-расширения оптимизированы под широкий диапазон программного обеспечения, в т.ч. аудио/видео кодеки, где они позволяют увеличить быстродействие обработки в 4 раза.

    Набор инструкций  SIMD для процессоров цифровой обработки сигналов (ЦОС)

Многие приложения предъявляют повышенные требования по быстродействию реально-временной обработки сигналов. Традиционно в таких ситуациях разработчики прибегают к использованию процессора ЦОС, что увеличивает энергопотребление и стоимость, как самой разработки, так и конечного устройства. Для устранения данных недостатков в ряд ARM-процессоров интегрированы инструкции ЦОС, выполняющие 16-32-х разрядные арифметические операции.

Усовершенствованный SIMD (NEON)

Расширение усовершенствованного SIMD, также называемое технологией NEON — это комбинированный 64- и 128-битный набор команд SIMD (single instruction multiple data), который обеспечивает стандартизованное ускорение для медиа приложений и приложений обработки сигнала. NEON может выполнять декодирование аудио формата mp3 на частоте процессора в 10Мгц, и может работать с речевым кодеком GSM AMR (adaptive multi-rate) на частоте более чем 13Мгц. Он обладает внушительным набором команд, отдельными файлами регистра, и независимой системой исполнения на аппаратном уровне. NEON поддерживает 8-,16-,32-,64-битную информацию целого типа, одинарной точности и с плавающей точкой, и работает в операциях SIMD по обработке аудио и видео (графика и игры). В NEON SIMD поддерживает до 16 операций единовременно.

VFP

Технология VFP (Vector Floating Point, вектора чисел с плавающей запятой) — это расширение сопроцессора в архитектуре ARM. Она производит низкозатратные вычисления над числами с плавающей запятой одинарной и двойной точности, в полной мере соответствующие стандарту ANSI/IEEE Std 754—1985 Standard for Binary Floating-Point Arithmetic.VFP производит вычисления с плавающей точкой, подходящие для широкого спектра приложений — например, для КПК, смартфонов, сжатие звука, 3д-графики и цифрового звука, а также принтеров и телеприставок. Архитектура VFP также поддерживает исполнение коротких векторных команд. Но, поскольку процессор выполняет операции последовательно над каждым элементом вектора, то VFP нельзя назвать истинным SIMD набором инструкций. Этот режим может быть полезен в графике и приложениях обработки сигнала, так как он позволяет уменьшить размер кода и выработку команд.

Другие сопроцессоры с плавающей точкой и/или SIMD, находящиеся в ARM процессорах включают в себя FPA, FPE, iwMMXt. Они обеспечивают ту же функциональность, что и VFP, но не совместимы с ним на уровне операционного кода.

Расширения безопасности

Расширения безопасности, позиционируемые как TrustZone Technology, находятся в ARMv6KZ и других, более поздних, профилированных на приложениях архитектурах. Оно обеспечивает низкозатратную альтернативу добавлению специального ядра безопасности, обеспечивая 2 виртуальных процессора, поддерживаемых аппаратным контролем доступа. Это позволяет ядру приложения переключаться между двумя состояниями, называемыми «миры» (чтобы избежать путаницы с названиями возможных доменов), чтобы не допустить утечку информации из более важного мира в менее важный. Этот переключатель миров обычно ортогонален всем другим возможностям процессора. Таким образом, каждый мир может работать независимо от других миров, используя одно и то же ядро. Память и периферия соответственно изготавливаются с учетом особенностей мира ядра, и могут использовать это, чтобы получить контроль доступа к секретам и кодам ядра. Типичные приложения TrustZone Technology должны запускать полноценную операционную систему в менее важном мире, и компактный, специализированный на безопасности, код в более важном мире, позволяя Digital Rights Management’у намного точнее контролировать использование медиа на устройствах на базе ARM, и предотвращая несанкционированный доступ к устройству.

На практике же, так как конкретные детали реализации TrustZone остаются собственностью компании и не разглашаются, остается неясным, какой уровень безопасности гарантируется для данной модели угрозы.

Рабочие состояния процессора

Поддерживаются следующие рабочие состояния:

ARM - в данном состоянии выполняются 32-разрядные команды ARM;

Thumb - в данном состоянии выполняются 16-разрядные команды Thumb.

В состоянии Thumb счетчик программы (PC) использует бит 1 для переключения между альтернативными полусловами.

Прим.: переход между состояниями ARM и Thumb не оказывает влияния на процессорный режим или содержимое регистров.

Изменение состояния

Рабочее состояние ядра  может переключаться между состоянием ARM и Thumb с помощью команды BX.

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

Форматы памяти

Программист   рассматривает память, как линейную совокупность байт, пронумерованных в возрастающем порядке, начиная с 0. Например,

  •  байты 0..3 представляют первое записанное слово;
  •  байты 4...7 представляют второе записанное слово.

Поддерживаются оба порядка следования байт многобайтных слов в памяти:

  •  Прямой порядок байт (Little-endian), когда сначала следует младший, а затем старший байты.
  •  Обратный порядок байт (Big-Endian), когда сначала следует старший, а затем младший байты.

Примечание: по умолчанию у ARM-процессоров используется прямой порядок байт (Little-endian).

Типы данных

Поддерживаются следующие типы данных:

  •  слова: 32 бит;
  •  полуслова: 16 бит;
  •  байты: 8 бит.

Их необходимо выровнять следующим образом:

  •  Значения слов необходимо выровнять в пределах 4 байт
  •  Значения полуслов необходимо выровнять в пределах 2 байт
  •  Значения байт могут располагаться в любых пределах байта.

Примечание: системы памяти, как правило, поддерживают все типы данных. В частности, система должна поддерживать запись подслов без повреждения смежных байт в слове.

Режимы работы

Поддерживаются семь режимов работы:

  1.  Режим пользователя - обычное состояние ARM-процессора  при выполнении программы, также используется для выполнения большинства прикладных программ.
  2.  Режим быстрого прерывания (FIQ), который поддерживает передачу данных или обработку канала.
  3.  Режим прерывания (IRQ), который используется для обработки прерываний общего назначения.
  4.  Супервизорный режим, который является защищенным режимом для операционной системы.
  5.  Аварийный режим, который вводится после аварийной выборки данных или команды.
  6.  Системный режим - привилегированный режим пользователя для операционной системы.

Примечание: Вводить системный режим из другого привилегированного режима можно только путем изменения бита режима в регистре текущего состояния программы (CPSR).

  1.  Неопределенный режим вводится, когда выполняется неопределенная инструкция.

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

Каждый регистр имеет идентификатор режима.

Регистры

Имеется 37 регистров:

  •  31 32-разрядных регистра общего назначения;
  •  6 регистров состояния.

Не все регистры доступны в одно и тоже время. Доступность регистров для программиста зависит от состояния процессора и рабочего режима.

Набор регистров в состоянии ARM

В состоянии ARM доступны 16 регистров общего назначения, один или два регистра состояния. В привилегированных режимах становятся доступными специфические банки регистров. На рисунке 3 демонстрируется, какие регистры доступны в каждом режиме.

Рис. 3. Организация регистров в состоянии ARM.

В набор регистров в состоянии ARM входят 16 регистров r0...r15. Еще один регистр, CPSR, содержит флаги условия кода и биты текущего режима. Регистры r0...r13 являются регистрами общего назначения и могут использоваться как для хранения данных, так и для хранения адреса. Регистры r14 и r15 выполняют следующие специальные функции:

Регистр связи

Регистр 14 используется как регистр связи (LR) подпрограммы.

Регистр r14 принимает копию регистра r15 при выполнении команды переход по ссылке (BL).

Во всех остальных случаях регистр r14 может использоваться как регистр общего назначения. Соответствующие банкированные регистры r14_svc, r14_irq, r14_fiq, r14_abt и r14_und аналогичным образом используются для запоминания значений возврата r15 при возникновении прерываний и исключительных ситуаций или при выполнении команды BL внутри процедур обработки прерываний или исключительных ситуаций.

Счетчик программы

Регистр 15 используется как регистр номера команды (PC).

В состоянии ARM биты [1:0] регистра r15 имеют неопределенное значение и должны игнорироваться. Биты [31:2] содержат значение PC.

В состоянии Thumb бит [0] имеет неопределенное значение и должен игнорироваться. Биты [31:1] содержат значение PC.

Регистр r13 iиспользуется в качестве указателя стека (SP).

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

Банки регистров - дискретные физические регистры в ядре, которые находятся в позициях доступных регистров в зависимости от текущего рабочего режима процессора. Содержимое банкированного регистра запоминается при изменениях рабочих режимов.

В режиме FIQ имеется семь банкированных регистров в позициях r8-r14 (r8_fiq-r14_fiq).

В состоянии ARM несколько обработчиков быстрых прерываний (FIQ) не должны выполнять запись в какой-либо регистр.

В режимах пользователя, IRQ, супервизорном, аварийном и неопределенном имеется два банкированных регистра в позиции r13 и r14, позволяя хранить собственное значение SP и LR в каждом режиме.

В системном режиме используются те же регистры, что и в режиме пользователя.


Набор регистров в состоянии Thumb

Набор регистров в состоянии Thumb является поднабором по отношению к набору регистров в состоянии ARM. Программист имеет доступ к:

  •  8 регистрам общего назначения r0-r7;
  •  Регистру номера команды (PC);
  •  Указателю стека SP;
  •  Регистру связи LR;
  •  Регистру текущего состояния программы CPSR.

В каждом привилегированном режиме имеются банкированные регистры SP, LR и SPSR. Данный набор регистров показан на рисунке 4.


Рисунок 4. Организация регистров в состоянии Thumb.

Соотношение между регистрами в состояниях ARM и Thumb

Регистры в состоянии Thumb связаны с регистрами в состоянии ARM следующим образом:

  •  Регистры r0-r7 в состоянии Thumb и регистры r0-r7 в состоянии ARM идентичны;
  •  Регистры CPSR и SPSR в состоянии Thumb и регистры CPSR и SPSR в состоянии ARM идентичны;
  •  Указатель стека SP в режиме Thumb совпадает с позицией r13 в состоянии ARM;
  •  Регистр связи LR в режиме Thumb совпадает с позицией r14 в состоянии ARM;
  •  Регистр PC в режиме Thumb совпадает с регистром PC в состоянии ARM (r15).

Данные соотношения показаны на рисунке 5.


Рисунок 5. Расположение регистров в состояниях Thumb и ARM.

Примечание: Регистры r0-r7 называются младшими регистрами, а регистры r8-r15 - старшими регистрами.

Доступ к старшим регистрам в состоянии Thumb

В состоянии Thumb старшие регистры r8-r15 не являются частью стандартного набора регистров. Программисту на языке Ассемблер ограничивается доступ к ним, но их можно использовать для кратковременного хранения.

Можно использовать специальные варианты команды MOV для передачи значений из младших регистров r0-r7 в старшие и, наоборот, из старших регистров в младшие. Команда CMP позволяет сравнивать значения старших регистров со значениями младших регистров, а инструкция ADD позволяет сложить значения старших регистров со значениями младших регистров.

Регистры состояния (статуса) программы

Имеются  регистр CPSR и пять регистров SPSR для использования в обработчиках исключительных ситуаций.

Регистры статуса программы:

  •  хранят информацию о большинстве недавно выполненных операциях АЛУ;
  •  управляют включением и отключением прерываний;
  •  устанавливают режим работы процессора.

Назначение разрядов показано на рисунке 6.


Рисунок 6. Формат регистра статуса программы

Примечание: В целях совместимости с будущими процессорами ARM не рекомендуется затрагивать значение зарезервированных разрядов. Один из способов сохранения неизменности этих разрядов - использование последовательности "чтение-модификация-запись" при изменении содержимого CPSR.

Исключительные ситуации

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

Таблица 3. Приоритет исключительных ситуаций

Приоритет

Исключительная ситуация

Наивысший

Сброс (Reset)

 

Авар. данные (Data Abort)

 

Запрос быстрого прерывания (FIQ)

 

Запрос прерывания (IRQ)

 

Авар. выборка (Prefetch Abort)

Низший

Неопределенная инструкция и программное прерывание (SWI)

Запрос быстрого прерывания

Исключительная ситуация запроса быстрого прерывания (FIQ) поддерживает передачу данных или обработку канала. В состоянии ARM режим FIQ имеет 8 банкированных регистров, что исключает необходимость предварительного запоминания регистров. Этим минимизируется потеря производительности при переключении контекста.

FIQ генерируется внешне путем удержания в низком состоянии входа nFIQ. Вход поступает в ядро через синхронизатор.

Независимо от того, в каком состоянии ARM или Thumb вводится исключительная ситуация, обработчик FIQ возвращается из прерывания путем выполнения команды:

SUBS PC,R14_fiq,#4

Исключительные ситуации FIQ могут быть отключены в привилегированном режиме путем установки флага F в CPSR. Если флаг F сброшен, то процессор ARM7TDMI проверяет наличие низкого уровня на выходе синхронизатора FIQ в конце выполнения каждой команды.

Запрос на прерывание

Исключительная ситуация запроса на прерывание (IRQ) - обычное прерывание, вызванное низким уровнем на входе nIRQ. IRQ имеет более низкий приоритет по сравнению FIQ и маскируется при вызове последовательности FIQ. Также как и вход nFIQ вход nIRQ поступает в ядро через синхронизатор.

Независимо от того, в каком состоянии ARM или Thumb вводится исключительная ситуация, обработчик IRQ возвращается из прерывания путем выполнения:

SUBS PC,R14_irq,#4

Отключить прерывание можно в любой момент путем установки бита I в регистре CPSR из привилегированного режима.

Аварийная ситуация

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

Аварийный механизм позволяет реализовать систему виртуальной памяти с подкачкой страниц по требованию. В таких системах процессор может генерировать произвольные адреса. Если данные по адресу не доступны, то блок управления памятью (MMU) сигнализирует об аварии.

Структуры процессоров Cortex A

Фирма ARM изменила схему названий процессоров. Ранее процессорные ядра обозначались на основании функциональных возможностей, специфичных для какой-то конкретной группы, отдельно велась нумерация версий архитектуры (и они не совпадали). Теперь принято решение называть самое современное ядро (с архитектурой ARMv7) именем собственным - Cortex (выйдет следующая модификация - будет новое имя).

Архитектура ARMv7 и, таким образом, процессоры Cortex разделены на три главных семейства: прикладные процессоры (А), процессоры для систем реального времени (R) и микроконтроллеры (М).

Прикладные процессоры  предназначаются для работы с открытыми операционными системами (ОС), содержат модуль управления памятью (MMU), обеспечивающий виртуальную адресацию и защиту памяти.

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

Микроконтроллеры вообще не имеют модулей MMU/MPU, но обеспечивают сверхнизкую латентность реакции и специфические средства (например, встроенные контроллеры флэш-памяти и прерываний).

Нумерация после буквы означает относительную градацию вычислительной мощности процессора  семействе (по десятибалльной шкале). Например,  Cortex-A15 - процессор для прикладных задач почти максимальной мощности. Менее производительная модификация, она будет называться, скажем, Cortex-A5, если встречается обозначение Cortex-R9, то понятно, что это мощный процессор для систем реального времени, Cortex-МЗ - маломощный микроконтроллер и т. д.

Процессор Cortex-A5

Процессор Cortex-A5 — самый маленький, низкопотребляющий, мультиядерный ARM-процессор, предназначенный для широкого круга устройств: от мобильных устройств типа смартфонов, коммуникаторов, мультимедийных проигрывателей и т. п. до встраиваемых пользовательских или индустриальных компьютеров.

Cortex-A5 обеспечивал примерно двукратный прирост отношения "производительность/потребляемая мощность" по сравнению со своими популярными предшественниками.

Структурная схема процессора ARM Cortex-A5 приведена на рис. 1.


Рис. 1.  Структурная схема процессора ARM Cortex-A5.

Одноядерный процессор Cortex-A5 имел 8-уровневый целочисленный конвейер, улучшенный блок предсказания ветвлений, модуль NEON, блок вычислений с плавающей точкой. Все блоки процессора были оптимизированы по потребляемой мощности и занимаемой площади.

Достигаемая производительность — 1.5 DMIPS/МГц. Производительность еще больше увеличивалась в многоядерной конфигурации Cortex-A5 MPCore.

Сравнительные характеристики  некоторых многоядерных ARM-процессоров представлены в таблице 1.

Таблица 1. Сравнительные характеристики некоторых многоядерных процессоров ARM

Процессор

Производительность ядра,DMIPS/МГц

Относительное энергопотребление,

мВт/МГц

Рабочие частоты,

МГц

Размер кэша (команд/данных), байт

ARM11 MPCore

1.0

0,23-0,43

320-620

16-64 К /16-64 К

ARM Cortex-A9 MPCore

2,0-2,5

<2000

16-64 К /16-64 К

ARM Cortex-A5 MPCore

1,5

0,12

480

4-64 К /4-64 К

Процессоры изготавливались по 40-нм технологии, рабочая частота — 480 МГц, занимаемая на кристалле площадь — 0,53 мм2 (без кэша — 0,27 мм2), размер кэша команд/данных — 16 Кбайт/16 Кбайт. Площадь, занимаемая процессором с кэшем и блоком расширения NEON — 0,68 мм2. Энергопотребление — 0,12 мВт/МГц. Показатель энергоэффективности — 13 DMIPS/мВт.

Многоядерный процессор  Cortex-A9 MPCore

Cortex-A9 MPCore поднял пиковую производительность на новый высокий уровень при одновременной поддержке простоты решений и возможностей контроля потребляемой мощности, как на уровне процессора, так и на уровне системы в целом.

Процессор Cortex-A9 MPCore имеет возможность оптимизации производительности приложений и по скорости выполнения, и по потребляемой мощности.

Его основные особенности следующие:

  •  Энергоэффективный суперскалярный конвейер производительностью более 2,0 DMIPS/МГц.
  •  Оптимизированный по производительности и потребляемой мощности кэш первого уровня совмещает минимальное время задержки и минимальное энергопотребление.
  •  Добавлен контролер кэша второго уровня, позволяющий осуществлять доступ с малыми временами задержки и высокой пропускной способностью к кэш памяти размером до 2 Мб.
  •  Многоядерный процессор Cortex-A9 MPCore обеспечивает практически линейную масштабируемость производительности на различных тестах.
  •  Процессоры ARM Cortex-A9 — и одиночный вариант (рис. 2), и многоядерный — поддерживают ряд специфических расширений ARM-архитектуры, в том числе: DSP, SIMD, Jazelle®, TrustZone, Intelligent Energy Manager.

На рис. 2 приведена структура одноядерногопроцессора ARM Cortex-A9.

Рис. 2.  Структура одноядерногопроцессора ARM Cortex-A9

Структура многоядерных процессоров Cortex-A5 MPCore и  Cortex-A9 MPCore представлена на рис. 3.

Рис. 3. Структура многоядерных процессоров Cortex-A9 MPCore   и  Cortex-A  MPCore

Процессор  Cortex A7

Как обеспечить постоянный рост производительности в рамках ограниченных по энергопотреблению устройств, каковыми являются смартфоны или планшеты? Можно создать более энергоэффективную структуру, но это возможно только до определённой степени. Можно перейти на более совершенный технологический процесс производства, но и этот шаг сегодня уже не даёт прежних преимуществ. Раньше фирмы полагались на оба подхода, но сегодня этого уже недостаточно. Индустрия постепенно идёт по пути гетерогенных вычислений: размещения высокопроизводительных ядер рядом с маломощными, но энергоэффективными собратьями, и переключения между ними при необходимости.

Фирма NVIDIA в  процессоре   Tegra 3 (Kal-El) реализовала  5 вычислительных ядер Cortex-A9, но лишь 4 из них видимы для операционной системы (ОС). При запуске простых фоновых задач работает только одно энергоэффективное ядро Cortex A9, а высокопроизводительные находятся в отключённом состоянии. Как только системе потребуется производительность, задачи перенаправляются на мощные ядра, а энергоэффективное отключается.

Решение фирмы NVIDIA полагается на идентичные ядра, но использующие различные транзисторы (LP и G), однако подход не слишком отличается, если использовать к тому же различные структуры ядер. Когда фирма NVIDIA разрабатывала свой процессор, фирма ARM не могла предложить подходящего энергоэффективного ядра, которое могло бы использоваться как само по себе, так и в качестве ядра-спутника в системе  с Cortex A15.

В последующем такое ядро было разработано, и оно получило имя Cortex A7.

На рис. 4  приведены показатели производительности и энергетической эффективности процессоров Cortex A8, Cortex A7 и 2-х ядерного Cortex A7.  

 

Рис. 4. Показатели производительности и энергетической эффективности процессоров Cortex A8, Cortex A7 и 2-х ядерный Cortex A7.  

 Начиная с процессора Cortex A9, фирма ARM перешла на исполнение команд с изменением последовательности (команды могут быть переупорядочены для улучшенного параллелизма) — этот переход структуры процессоров с архитектурой x86 совершила фирма Intel  еще впроцессоре Pentium Pro (1995 г.). Cortex A15 развил эту тенденцию, расширяя при этом число исполняемых за такт команд. Cortex A7, напротив, был шагом назад: это ещё одно ядро, исполняющее команды в заданной последовательности и способное выполнить до двух команд одновременно. Описание напоминает Cortex A8, однако CortexA7 отличается во многих областях.

Ядро CortexA8 является очень старой разработкой — работы над проектом начались ещё в далёком 2003 году. Хотя ARM предлагала легко синтезируемые версии ядра, для достижения более высоких частот со временем производителям пришлось использовать собственную дополнительную логику. Создание отдельного проекта не только удлиняло время вывода решений на рынок, но и увеличивало затраты на разработку.

Cortex A7 был полностью синтезируемым, но при этом предлагал хороший уровень производительности. ARM при разработке структуры учла последние технологические процессы производства, добившись хорошего соотношения тактовых частот и производительности, а также пересмотрела структуру, дабы уменьшить время и стоимость вывода решений на рынок.

В ядре процессора Cortex A7 применяется 8-ступенчатый конвейер, обрабатывающий по две команды за такт (впрочем, некоторые сложные команды CortexA7, в отличие от CortexA8 ,исполняет в режиме одну за такт). Блок целочисленных операций в Cortex A7 аналогичен CortexA8, а вот математический сопроцессор имеет полностью конвейерную организацию и более компактен, хотя и несколько упрощён.

Некоторое упрощение структуры позволило существенно сократить размер ядра. Одно ядро Cortex A7  занимает всего 0,5 мм2 при использовании 28-нм техпроцесса. При одном и том же процессе производства клиенты ARM смогут разместить ядро A7 на площади всего в 1/3—1/2 ядра Cortex A8. Стандартный дизайн ядер Cortex A9 по площади соответствует Cortex A8, тогда как площадь Cortex A15 больше, чем у обоих.

Несмотря на ограниченные возможности в выполнении сложных команд, структура Cortex A7 обеспечивает более высокую производительность по сравнению с Cortex A8. Это частично достигается благодаря усовершенствованному модулю предсказания ветвлений и уменьшенному конвейеру, сокращающему вероятность неправильного предсказания перехода.

Cortex A7 отличается улучшенными алгоритмами выборки команд и более скоростной кеш-памятью L2, что также позволяет увеличить общую эффективность вычислений.

Впрочем, из-за некоторых ограничений в определённых задачах производительность Cortex A7  находится на уровне с Cortex A8 или даже уступает последнему. Рейтинг  производительности DMIPS/МГц для различных ядер ARM выглядит так:

  •  ARM11 — 1,25 DMIPS/МГц;
  •  ARM Cortex A7 — 1,9 DMIPS/МГц;
  •  ARM Cortex A8 — 2 DMIPS/МГц;
  •  ARM Cortex A9 — 2,5 DMIPS/МГц;
  •  Qualcomm Scorpion — 2,1 DMIPS/МГц;
  •  Qualcomm Krait — 3,3 DMIPS/МГц.

Характеристики различных структур процессоров приведены в таблице 2.

Таблица 2.

 

 Важнее же всего то, что ядра Cortex A7 является на 100% совместимыми по системе команд с Cortex A15, то есть поддерживают новые команды виртуализации и 40-битную адресацию памяти. В результате любая программа, написанная для Cortex A15, может исполняться на Cortex A7, только медленнее. Это очень важная характеристика, которая позволяет производителям проектировать системы на кристалле, оснащённые как ядрами Cortex A7, так и Cortex A15, переключаясь между ними в зависимости от задачи. Фирма ARM называет это конфигурацией big.LITTLE.

Структура Cortex A15 стала значительным шагом вперёд с точки зрения производительности структур ARM. Она нацелена на противостояние с процессорами с архитектурой  x86 начального уровня.

Ядра Cortex A15 используются в  смартфонах и планшетах, вытеснив Cortex A9 в решениях высокого класса. В сложных задачах Cortex A15 более энергоэффективные, чем Cortex A9.

Однако фоновые и простейшие задачи на смартфонах подчас не нуждаются в такой производительности, и их исполнение на мощном ядре Cortex A15 не очень эффективно с точки зрения потребления энергии. Здесь-то и выходит на первый план CortexA7. Хотя Cortex A7 можно применять в качестве самостоятельных вычислительных ядер (и, конечно, они   так и используются в дешёвых аппаратах), партнёры ARM могут интегрировать ядра Cortex A7 наряду с Cortex A15 в конфигурации big.LITTLE.

На рис. 5 показа структура конфигурации big.LITTLE с перечнем существенных особенностей составляющих ее процессоров Cortex A7 и Cortex A15.

 

Рис. 5. Структура конфигурации big.LITTLE с перечнем существенных особенностей составляющих ее процессоров Cortex A7 и Cortex A15.

Так как  Cortex A7 и Cortex A15 могут исполнять одни и те же команды, системы на кристалле, оснащённые ядрами обеих структур, могут переключать задачи с энергоэффективных на высокопроизводительные, в зависимости от необходимости. Непротиворечивость содержания кешей обеспечивается связью CCI-400. Микросхема может переключаться между кластерами с различными ядрами за 20 миллисекунд.

Такая структура оказывается полностью прозрачной для ОС, как и в случае с Tegra 3, и нет необходимости в программных оптимизациях для увеличения энергоэффективности. Впрочем, производители смогут ставить ОС в известность о реальном числе вычислительных ядер, если им будет необходим такой подход.

На базе Cortex A7 можно  создавать процессоры, оснащённые от 1 до 4 таких ядер, как самостоятельных, так и в конфигурации с Cortex A15.

Микросхемы с Cortex A7  применяются в дешёвых 2-ядерных смартфонах стоимостью до $100 и ещё более дешёвых одноядерных. Также в будущем  должны появиться  28-нм микросхемы, объединяющие как ядра Cortex A7, так и Cortex A15 на едином кристалле.

 Таким образом, Cortex A7 является отличной структурой, обеспечивающей  гораздо более высокое соотношение производительности и цены по сравнению с Cortex A8,  и значительно увеличивающей время автономной работы смартфонов, как высокого класса, так и начального уровня. Эра неоднородных вычислений, как следующая фаза развития процессоров уже наступила.

Процессор  Cortex-A8 

Процессорное ядр  Cortex-A8 работатало при тактовых частотах до 1 ГГц. Кристалл производился  по 65-нм технологическому процессу, быстродействие на синтетических тестах составляло до 2000 DMIPS (1 ГГц), максимальное энергопотребление 300 мВт.

Кристалл построен по архитектуре ARMv7, имеет двойной симметричный конвейер с упреждающей выборкой, суперскалярное  ядро, 13-ступенчатый целочисленный конвейер, кэш-память второго уровня, ряд фирменных подсистем (Jazelle, TrustZone и так далее). Емкость кэша от 64 Кбайт до 2 Мбайт.

Cortex-A8 - ориентирован на задачи, требующие быстродействия на уровне 2000 MIPS Dhrystone (DMIPS) при невысоком энергопотреблении и тепловыделении (последнее особенно важно, поскольку предоставляет возможность дальнейшей миниатюризации мобильных устройств).

Структура   Cortex-A8 приведена на рис. 6.

Рис. 6.Структура   Cortex-A8 .

Структура конвейера Cortex-A8   приведена на рис. 7.

Рис. 7. Структура конвейера Cortex-A8.   

Структура блоков дешифрации и выполнения Cortex-A8 приведена на рис. 8.

 

Рис. 8.  Структура блоков дешифрации и выполнения Cortex-A8.

Структура блока выполнения Cortex-A8 приведена на рис. 9.

Рис. 9. Структура блока выполнения Cortex-A8.

Структура блока   NEON Cortex-A8 приведена на рис. 10.

Рис. 10. Структура блока   NEON Cortex-A8.

Структура связей бока NEON с остальной частью  Cortex-A8  приведена на рис. 11.

Рис. 11.Структура связей бока NEON с остальной частью   Cortex-A8.

Структура конвейера блока   NEON приведена на рис. 12.

Рис. 12. Структура конвейера блока   NEON.

В микросхеме реализована система команд Thumb 2 (обеспечивается "упаковка" 32-разрядных команд в 16-разрядные, что повышает "плотность" программного кода и важно при подготовке модулей, записываемых в ПЗУ. Улучшение плотности "упаковки" машинного кода в Thumb 2 связано с внесением в систему команд ряда дополнительных команд (130). Поскольку Thumb - 16-разрядная система команд, на которую отображается основное подмножество 32-разрядных команд ARM, но поскольку оставались "неэмулируемые" команды, приходилось писать дополнительный код для реализации тех действий, которые решает единственная 32-разрядная инструкция. Важнейшая особенность - отсутствие необходимости переключаться между режимами ARM и Thumb при обработке прерываний и доступ к полному набору регистров. В итоге сохраняется высокая плотность упаковки команд, свойственная Thumb, и скорость, как правило, на уровне программ с 32-разрядными командами ARM.

Подсистема NEON предназначена для повышения быстродействия при обработке потоковых данных. Концептуально здесь нет ничего особенно нового, но если до сих пор для решения таких задач изготовители кристаллов и партнеры ARM использовали собственные расширения (классический пример - DSP в TI ОМАР), то теперь они внесены в структуру процессорного ядра (и изготовителям достаточно задействовать этот модуль). В TI ОМАР 3430 (где применяется Cortex-A8), хотя и имеются специализированные модули обработки такого рода данных, уже не идет речи о наличии отдельной микросхемы (вернее, топологической ячейки) с полномасштабным DSP, фактически "пристроенным" к прикладному ядру. У NEON имеется собственная подсистема обработки сигнала, система команд - 64/128-разрядная гибридная SIMD, с собственным банком регистров и конвейером. Она позволяет обрабатывать как целочисленную арифметику, так и предоставляет средства вычислений с плавающей точкой, возможность загрузки структурированных данных (допускается работа с данными, не выровненными по границам машинного слова, байта и т. д.). По оценкам ARM, использование NEON позволяет добиться стабильной скорости 30 кадр/с при декодировании видеопотока VGA MPEG-4 (в том числе спецэффектов, преобразований YUV2RGB и т. д.) при тактовой частоте 275 МГц, а видео Н.264 - в 350 МГц. Кроме того, NEON можно использовать для обработки традиционных данных (это также существенный плюс в сравнении с применением "накристального" DSP).

Средства Jazelle RCT обеспечивают снижение размера Java-программ (до 70%) за счет динамического преобразования (JIT) байт-кода (что закономерно повышает скорость и снижает энергопотребление). TrustZone - традиционная для ARM система реализации защиты, которая представляет  большой интерес как основа для реализации DRM и защиты мобильного контента. Фактически она позволяет динамически переключать процессор в "безопасный" режим и общий, причем в первом допускается выполнение только "безопасных" программ (например, размещенных в заранее заданном блоке).

Улучшена подсистема вычислений с плавающей точкой (VFPv3). В частности, до 32 увеличено число регистров для вычислений с двойной точностью, реализованы команды для преобразования чисел с плавающей и фиксированной точкой.

С технической точки зрения одна из наиболее существенных особенностей - система "статического планирования" для суперскалярного целочисленного конвейера. Выгоды суперскалярности очевидны, но за них приходится расплачиваться усложнением логики работы процессора, что создает сложности при оптимизации энергопотребления (особенно если выясняется, что ожидания блока предвыборки не оправдалось - цикл кончился - и приходится сбрасывать внутренние буферы, подавая питание на соответствующие модули). Хитрый способ решения этой проблемы, использованный ARM, состоит в том, чтобы использовать сдвоенный АЛУ с двумя конвейерами (ALU0 и ALU1). Они симметричны, могут обрабатывать большинство арифметических команд, но конвейер ALU0 всегда обрабатывает более старую из пары поступивших команд. При необходимости процессор просто переключает конвейер. Операции умножения и загрузки вынесены на соответствующие конвейеры, они могут "спариваться" только с "зависимым" конвейером (умножение - только с нулевым АЛУ, загрузка - с соответствующим).

Конвейер - 13-ступенчатый, на протяжении работы собирается статистика, которая затем используется при предсказании ветвлений (размещается в буфер меток перехода и глобальный буфер хронологии, GHB). Кроме ветвлений, прогнозируется и стек возвращения (для прогнозирования адресов возврата из подпрограмм).

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

При этом обработка команд NEON начинается в конце главного целочисленного конвейера (соответственно все предсказания ветвлении, результаты операции и прочее уже отработаны), и, что важнее, все необходимые данные уже находятся в кэше первого уровня.

Средства буферизации данных между блоками ARM и NEON также позволяют нивелировать влияние многоступенчатой буферизации при изменении содержимого кэша (для потоковых данных это может быть критично). Сам модуль NEON не связан с главным целочисленным конвейером ARM.

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

Cortex-A8 представляет собой комплект модулей синтезируемых ядер, топологических ячеек или заказных схем. Предусматривается семь функциональных модулей, каждый из которых разделен на несколько блоков; модуль реализуется в наиболее подходящем варианте. Такая структура существенно упрощает интеграцию и построение на основе данного процессора готовых микросхем. ARM предоставляет описание процесса подготовки и рекомендации по изготовлению кристаллов на базе ARM Cortex-A8.

Cortex-A8 применялся в в бюджетных смартфонах. Это было недорогое решение с частотой от 600 МГц до 1 ГГц со сбалансированной структурой. Он имеет блок FPU, поддерживал первый вариант SIMD NEON. Cortex-A8 выпускался только 65-нм техпроцессу.

Процессор Cortex A9

Структура одноядерного процессора  Cortex-A9 приведена на рис.13.

Рис. 13.Структура  одноядерного процессора ARM Cortex-A9.

Структура 4-х ядерного процессора  Cortex-A9 приведена на рис. 14.

Рис. 14. Структура 4-х ядерного процессора  Cortex-A9.

Структура когерентного ускорителя процессора  Cortex-A9 приведена на рис. 15.

Рис. 15. Структура когерентного ускорителя процессора  Cortex-A9.

Зависимость производительности процессора  Cortex-A9 от количества ядер приведена на рис. 16.

Рис. 16. Зависимость производительности процессора  Cortex-A9 от количества ядер.

Набор SIMD-команд NEON Advanced и блок FPU в Cortex-A9 являются опциональными элементами.

Cortex-A9 предназначен для использования в высокопроизводительных смартфонах ипланшетах, но более серьезное применение, например, в серверах ему не по зубам.

Cortex-A9  выпускается как во много-, так и одноядерном варианте по техпроцессам 65 и 40 нм. Максимальная частота составляет 2.0 ГГц.

Процессор Cortex-A15

Наиболее совершенная и мощная структура в линейке процессоров фирмы ARM – процессор Cortex-A15. На его базе  производятся, в основном, двух или четырехъядерные модели. Cortex-A15 из всех предыдущих процессоров фирмы ARM наиболее близок к процессорам с архитектурой  х86 по количеству и качеству блоков.

Структура 4-х ядерного процессора  Cortex-A15 приведена на рис. 17.

Рис. 17. Структура 4-х ядерного процессора  Cortex-A15.

Процессор Cortex-A15 в своем составе имеет:

блок FPU;

набор SIMD-команд NEON, призванных ускорить обработку мультимедийных данных;

ядра имеют:

13-стадийный конвейер;

поддерживают выполнение команд в свободном порядке, виртуализацию.

Cortex-A15 поддерживает систему расширенной адресации памяти. Хотя Cortex-A15  имеет  32-битную архитектуру, однако он умеет преобразовывать 64-битную или другую расширенную адресацию в понятную процессору 32-битную. Технология получила название Long Physical Address Extensions. Благодаря ей, Cortex-A15 в теории может адресовать до 1 Тбайт памяти.

Каждое ядро снабжено кэшем первого уровня. Кроме того, есть до 4 Мбайт распределенного кэша второго уровня с низким уровнем латентности. Процессор снабжен 128-битной когерентной шиной, которая может быть использована для связи с другими блоками и периферией.

Ядра, которые лежат в основе Cortex-A15 являются развитием Cortex-A9. Они имеют схожую структуру.

Cortex-A15 предполагает возможность создания микросхем, работающих на частоте 2.5 ГГц. Микросхемы Cortex-A15  предусмотрено изготавливать по техпроцессам 40 нм и более тонким.

Cortex-A15 поддерживает  аппаратную виртуализацию, расширенную адресацию памяти.

Набор SIMD-команд NEON Advanced и блок FPU в Cortex-A15  обязательны.

Общая характеристика мультиядерных ARM-процессоров

 

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

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

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

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

Многоядерные процессоры  позволяют производителю использовать одни и те же ядра с разными конфигурациями для продуктов с различными свойствами и требованиями.

Лицензию на выпуск многоядерных процессоров ARM  приобрели более чем 15 компаний, включая Broadcom, NEC Electronics, NVIDIA, Renesas Technology, Toshiba и Sarnoff Corporation. Эти процессоры использованы в большом количестве приложений и устройств, представленных на современном рынке. Технология существенно расширяет спектр приложений, предлагая более эффективные модели операций.

Все многоядерные решения от ARM базируются на шинной структуре AMBA 3 AXI, дающей возможность подключать к процессорам не только память и периферийные устройства, но и другие процессоры. Шинный интерфейс многоядерных процессоров  и масштабируемость позволяют настраивать производительность системы, оптимизировать ее энергопотребление при снижении общей стоимости решения и риска его морального старения при переходе к следующему поколению цифровых устройств. Интеграция с существующими системными компонентами также снижает риски, связанные, например, с поддержкой операционных систем и продуктов на базе данных процессоров. Поддерживается стандартная для ARM-архитектур модель программирования с поддержкой существующих операционных систем и приложений. Доступны совместимые с Linux 2.6 SMP операционные системы и инструменты разработки.

Занимаемая процессорами площадь на кристалле, диапазон рабочих частот и потребляемая мощность зависят от использованного при реализации технологического процесса, библиотек компонентов и оптимизации.

Несмотря на различия в ядрах и некоторые различия в построении многоядерных вариантов процессоров есть ряд технологий, поддерживаемый ими всеми.

Технологии ускорения выполнения lava-приложений — Jazelle DBX и Jazelle RCT—необходимы для оптимизации процесса адаптивной компиляции на лету (Just In Time, JIT и Dynamic Adaptive Compilation, DAC), а также уменьшения расхода памяти до трех раз.

Технология TrustZone применяется для обеспечения безопасности транзакций, управления цифровыми сертификатами, создания базы для проверки и защиты прав (Digital Rights Management, DRM).

Перспективы процессоров ARM

В настоящее время продолжается острая конкуренция между процессорами фирмы ARM и Intel. Фирма Intel пытается отвоевать значительную часть рынка, которая занята процессорами с архитектурой ARM.

Так на какую архитектуру ставить в итоге, на ARM или х86? Наиболее правильно будет ставить на обе. Сегодня мир живет в условиях переформатирования компьютерного рынка. В 2008 году нетбукам предрекали безоблачное будущее. Дешевые компактные ноутбуки должны были стать основным компьютером для большинства пользователей, особенно на фоне мирового кризиса. Но затем началось восстановление экономики и появился планшет iPad. Теперь королями рынка объявлены планшеты. Однако планшет хорош в качестве развлекательной консоли, но не очень удобен для работы в первую очередь из-за сенсорного ввода. Выдержат ли планшеты проверку временем. Возможно, через несколько  лет мир придумает  себе новую игрушку.

Но все-таки в мобильном сегменте, там, где не требуется высокой производительности, а активность пользователя в основном ограничена развлечениями, и не связана с работой, процессоры ARM выглядят предпочтительнее процессоров х86. Они обеспечивают приемлемый уровень производительности, а также большое время автономной работы. Попытки фирмы Intel довести до ума процессор Atom пока неудачны. ARM задает новую планку производительности на ватт потребляемой энергии. Скорее всего, в компактных мобильных гаджетах ARM будут пользоваться успехом. На рынке нетбуков они также могут стать лидерами, но здесь все зависит не столько от разработчиков процессоров, сколько от фирм Microsoft и Google. Если первая реализует нормальную поддержку процессоров ARM в Windows 8, а вторая доведет до ума Chrome OS. Пока же смартбуки, предложенные Qualcomm, не сделали рынка. Нетбуки на базе х86 устояли.

Особенности архитектуры ARMv8

В конце 2011 года компания ARM представила  новую разработку - архитектуру ARMv8 (рисунок 1).


Рисунок 1 – Архитектура ARMv8.

В архитектуре ARMv8 соблюден один из наиважнейших принципов  при внедрении новых технологий - абсолютно полная обратная совместимость с ARMv7.

В архитектуре ARMv8 два основных режима исполнения - AArch64  и AArch32.

В режиме AArch64 используется новый набор команд А64 с 32-разрядными инструкциями и 5-разрядными спецификаторами регистров для доступа к 32/64/128-разрядным регистрам. При выполнении большинства команд доступен выделенный нулевой регистр. Указатель стека и счетчик команд не входят в группу регистров.

Новые команды поддерживают 32- и 64-разрядные аргументы. В наборе А64 отсутствует несколько команд загрузки или хранения произвольной длины. Поддержка архитектуры SIMD и операций с плавающей точкой схожи с поддержкой предыдущей версией – ARMv7.

В архитектуре ARMv8 используются четыре иерархических уровня привилегий (EL0-EL3). EL3 поддерживает технологию TrustZone. Эта система поддерживает множество 32- и 64-разрядных конфигураций безопасной виртуализации.

Когерентность всей связки «процессоры – кэш – шина – графический ускоритель» и возможность использования графического ядра в роли сопроцессора позволяет создавать невероятно мощные, но в то же время очень энергоэффективные, серверные решения. И поддержка 64 бит максимально расширяет эти возможности.

В новой архитектуре появился режим Embedded Trace Mode 4 (ETM4), который расширяет адреса до 64 бит. Он позволяет выявить «промежуточные этапы» выполнения команд, что эффективнее, чем предоставление информации об адресах. Аппаратная поддержка криптографии, способная ускорить процессы, использующие шифрование, в десятки раз.

В архитектуре ARMv8 предусмотрены отличные возможности масштабируемости: до 4-х ядер внутри одного чипа, и до 16 в одном кластере.

Архитектура ARMv8 сохраняет  и приумножает ключевые функции своей предшественницы, такие, как TrustZone, SIMD-инструкции NEON и виртуализация, которая позволит устанавливать на мобильные платформы гипервизоры виртуальных машин, обеспечивающие работу нескольких гостевых операционных систем. Например, использование новинки от Microsoft системы WOA (Windows On ARM) обеспечит пользователя постоянным доступом к корпоративной среде, а насыщенный программным обеспечением и параллельно работающий Android будет применяться для социальной активности и развлечений.

Технология ARM TrustZone  - это общесистемный подход к безопасности для широкого спектра клиентских и серверных платформ, включая телефоны, планшеты и т. д. TrustZone представляет собой набор расширений безопасности, добавленных в процессоры с архитектурой ARMv6 и выше. Для повышения безопасности, эти ARM процессоры могут одновременно запускать безопасную операционную систему и нормальную операционную систему с одного ядра. Технология TrustZone программируется в аппаратные средства, что позволяет защитить память и периферийные устройства.

SIMD (single instruction, multiple data - одиночный поток команд, множественный поток данных) - принцип компьютерных вычислений, позволяющий обеспечить  параллелизм на уровне данных. Одним из преимуществ данной архитектуры считается то, что в этом случае более эффективно реализована логика вычислений.

Технология ARM NEON - это набор из 64- и 128-битовых SIMD-инструкций, который предоставляет стандартизированное ускорение для средств медиа и сигнальной обработки прикладных программ, повышая качество обслуживания пользователей.

Архитектура Cortex M3

Версия архитектуры процессора Cortex M3 - ARMv7M (рис. 1).

Рис. 1. Версии архитектуры процессоров ARM

Cortex-M - микроконтроллерный профиль, оптимизированный под требования где одновременно необходимы низкая стоимость, высокая 32-разрядная разрядная производительность и малое энергопотребление. Поддерживает только набор команд Thumb-2.

Число, завершающее наименование процессора Cortex, указывает на его уровень рабочих характеристик, причем 1 указывает на самый низкий уровень, а 8 - на самый высокий.  

Несмотря на то, что ядро Cortex-M3 разрабатывалось как недорогое ядро, оно остается 32-разрядным и, в связи с этим, поддерживает два режима работы: потоковый режим (Thread) и режим обработчика (Handler), для каждого из которых можно сконфигурировать свои собственные стеки. Благодаря этому, появляется возможность разработки более интеллектуального программного обеспечения и поддержки операционных систем реального времени (ОСРВ).

В ядро Cortex также входит 24-разрядный автоматически перезагружаемый таймер, предназначенный для генерации периодических прерываний и используемый ядром ОСРВ.

У семейства Cortex М предусмотрена поддержка набора команд ARM Thumb-2. Он представляет собой смесь 16- и 32-разрядных команд, позволяющие добиться производительности 32-разрядного набора команд ARM и плотности кода, свойственной 16-разрядному набору команд Thumb. Thumb-2 - обширный набор команд, ориентированный на компиляторы языков C/C++. Это означает, что программа для Cortex-микроконтроллера может быть полностью написано на языке высокого уровня Си.

Распределение памяти

Адресное пространство (рис. 2) для программиста предлагается как линейное размером 4 Гбайт. В  МК,  выполненных на основе архитектуры Cortex,  используется стандартное распределение памяти.

Память программ начинается с адреса 0x00000000.

Встроенное статическое ОЗУ стартует с адреса 0x20000000. Все ячейки статического ОЗУ расположены в области хранения разряд.

Регистры УВВ представлены в карте памяти, начиная с адреса 0x40000000, и также расположены в области хранения разрядов  УВВ.

Регистры Cortex находятся в их стандартном месте, начиная с адреса 0xE0000000.


Рис.2.

Первые 2 кбайт памяти могут быть связаны с Flash памятью, системной памятью или статическим ОЗУ, в зависимости от состояния выводов управления загрузкой.

Область Flash памяти разделена на три секции. Первая - Flash память пользователя - начинается с адреса 0x0000000. Далее следует системная память, которая также называется большим информационным блоком. Она представляет собой Flash память размером 4 кбайт, которая запрограммирована производителем кодом программы загрузчика. Последняя секция, которая стартует с адреса 0x1FFFF800, называется малым информационным блоком. В ней находится группа опциональных байт, с помощью которых можно повлиять на некоторые системные настройки микроконтроллера. Программа загрузчика позволяет посредством интерфейса USART1 загрузить код программы и запрограммировать его во Flash память пользователя. Чтобы перевести микроконтроллер в режим загрузчика, нужно на внешних выводах BOOT0 и BOOT1 установить низкий и высокий уровни, соответственно. Если установить именно такие состояния на выводах управления загрузкой, то блок системной памяти начнется с адреса 0x00000000. После сброса микроконтроллер, вместо выполнения прикладного кода из Flash памяти пользователя, начнет выполнение программы загрузчика.

С помощью выводов управления загрузкой адрес 0x00000000 вместо Flash памяти пользователя может быть также связан со статическим ОЗУ. Поскольку загрузка статического ОЗУ осуществляется более быстро, то эта возможность может оказаться полезной на фазе проектирования для исполнения кода программы из статического ОЗУ. Кроме того, появляется возможность сократить частоту перепрограммирования Flash памяти.

Карта памяти

Для процессора Cortex-M3 определена фиксированная карта памяти размером 4 Гбайт, в которой выделены конкретные области для хранения кода программы, статического ОЗУ, устройств ввода-вывода, внешней памяти и устройств, а также системных регистров Cortex. Данная карта памяти (рис. 3) одинакова для всех Cortex-микроконтроллеров.

Адресное пространство является линейным и имеет размер 4 Гбайт. Первые 1 Гбайт памяти разделены равномерно между областью кода программы и областью статического ОЗУ. Пространство кода программы оптимизировано для работы с шиной I-Code. Аналогично, пространство статического ОЗУ доступно через шину D-code. Несмотря на то, что в области статического ОЗУ поддерживается загрузка и исполнение команд, их выборка осуществляется через системную шину, что требует дополнительного состояния ожидания.

Таким образом, выполнение кода программы из статического ОЗУ будет более медленным, чем из встроенной Flash памяти, расположенной в области кода программы. Следующие 0.5 Гбайт памяти - область встроенных УВВ. В этой области находятся все предоставляемые пользователю производителем микроконтроллера УВВ. Первые 1 Мбайт в областях статического ОЗУ и УВВ являются разрядноадресуемыми. Для этого используется метод bit banding. Таким образом, все данные, хранящиеся в этих областях, могут обрабатываться как пословно, так и поразрядно. Следующие 2 Гбайт адресного пространства выделены для внешних статического ОЗУ и УВВ. Последние 0.5 Гбайт зарезервированы для системных ресурсов процессора Cortex и будущих расширений процессора Cortex. Все регистры процессора Cortex расположены по фиксированным адресам во всех Cortex-микроконтроллерах. Благодаря этому, облегчается перенос программ между микроконтроллерами других производителей.


Рис. 3.

Доступ к фрагментированным данным

ЦПУ Cortex поддерживает режимы адресации для слов, полуслов, байт и может осуществлять фрагментированный доступ к данным. Благодаря этому, линкеру компилятора предоставляется полная свобода в очередности размещения данных в памяти. Кроме того, поддерживаемая ЦПУ Cortex возможность bit banding позволяет группировать флаги программы в переменные типа слово или полуслово, а не использовать для каждого флага отдельный байт.

Метод "Bit Banding"

Способ bit banding позволяет напрямую воздействовать на разряды в памяти из областей УВВ и статического ОЗУ, не используя при этом каких-либо специальных команд. Разрядноадресуемые области карты памяти Cortex разделены на две части: область хранения разрядов (в нее входят до 1 Мбайт физической памяти или регистров УВВ) и область доступа к разрядам, которая занимает до 32 Мбайт карты памяти. Получить доступ к каждому отдельному разрядуу из области хранения разрядов можно по соответствующему адресу слова из области доступа к разрядамам. Таким образом, если выполнять запись по адресу в области доступа к разрядам на самом деле  будет воздействие на значение определенного разряда в физической памяти.


Рис. 4.

Модель программирования

Cortex является RISC-процессором, который выполнен по архитектуре чтения/записи. Для выполнения операций обработки данных вначале необходимо поместить операнды из памяти в центральный регистровый файл, затем выполнить требуемую операцию над данными в регистрах и, наконец, перезаписать результат обратно в память (рис. 5).


    Рис. 5.

   

Регистровый файл образуют шестнадцать 32-разрядных регистров (рис. 8). Регистры R0-R12 - обычные регистры, которые могут использоваться для хранения программных переменных. У регистров R13-R15 имеются особые функции в рамках ЦПУ Cortex.

Регистр R13 выступает в роли указателя стека. Данный регистр является альтернативным (банковым), что делает возможной работу ЦПУ Cortex в двух режимах работы, в каждом из которых используется свое собственное пространство стека. Эта  возможность обычно используется операционными системами реального времени (ОСРВ), которые могут выполнять свой "системный" код в защищенном режиме. У двух стеков ЦПУ Cortex имеются собственные наименования: основной стек и стек процесса.

XPSR

Рис. 6

Следующий регистр R14 называется регистром связи. Он используется для хранения адреса возврата из подпрограммы. Благодаря нему, ЦПУ Cortex быстро переходит к подпрограмме и выходит из нее. Если же в программе используется несколько уровней вложений подпрограмм, то компилятор будет автоматически сохранять R14 в стек.

Последний регистр R15 - счетчик программы; поскольку он является частью центрального регистрового файла, его чтение и обработка может выполняться аналогично любым другим регистрам.

Помимо регистрового файла, имеется регистр статуса программы. Он не входит в основной регистровый файл, а доступ к нему возможен с помощью двух специальных команд. В xPSR хранятся значения полей, влияющих на исполнение команд ЦПУ Cortex.


Рис. 7.

Регистр статуса программы содержит поля статуса, от которых зависит исполнение команд. Данный регистр разделен еще на три регистра: регистры статуса прикладной программы, исполнения программы и прерываний

Также как и 32-разрядные инструкции ARM, некоторые инструкции Thumb-2 выполняются только при условии совпадения кода условия инструкции и состояния флагов регистра статуса прикладной программы. Если коды условия инструкции не совпадают, то команда проходит по конвейеру как NOP (нет операции). Этим гарантируется равномерность прохождения команд по конвейеру и минимизируется число перезагрузок конвейера. У Cortex данный способ расширен регистром статуса исполнения программы, который связан с разрядами 26…8 регистра xPSR. Этот регистр состоит из трех полей: поле "If then" (IT), поле возобновляемой прерыванием инструкции и поле инструкции Thumb. Набор команд Thumb-2 реализует эффективный метод выполнения компактных блоков команд типа 'if then'. Если проверяемое условие истинно, записью значения в поле IT можно сигнализировать ЦПУ о необходимости выполнения до четырех следующих команд. Если же проверяемое условие - ложное, то данные инструкции пройдут по конвейеру как NOP.  

Несмотря на то, что большинство команд Thumb-2 выполняются за один цикл, несколько команд (например, инструкции чтения/записи) требуют для выполнения несколько циклов. Чтобы точно знать время отклика ЦПУ Cortex на прерывания, данные инструкции должны быть прерываемыми. В случае преждевременного прекращения исполнения инструкции в поле возобновляемых прерываниями команд запоминается номер следующего регистра, подлежащего обработке инструкцией многократного чтения или записи. Таким образом, сразу после завершения процедуры обработки прерывания, выполнение инструкции многократного чтения/записи может быть восстановлено. Последнее поле Thumb предусмотрено для совместимости с предшествующими ЦПУ ARM. Данное поле сигнализирует, что в данный момент ЦПУ выполняет инструкцию ARM или Thumb. У ЦПУ Cortex-M3 данный разряд всегда равен единице. Наконец, в поле статуса прерывания хранится информация о любых приостановленных запросах прерывания.

Набор команд 

Набор команд Thumb-2 являлся развитием набора команд Thumb, применявшихся в прежних моделях ядер фирмы ARM, и сохранял обратную совместимость с существующими решениями.  В него были добавлены:

  •  новые 16-разрядные Thumb-инструкции для улучшенного управления ходом программы;
  •  новые 32-разрядные Thumb-инструкции, заменяющие 32-разрядные ARM-инструкции;
  •  новые 32-разрядные инструкции для повышения производительности и для обработки данных.

Добавлены инструкции для доступа к регистрам сопроцессора и специальным функциям SIMD, а также привилегированные функции, дающие, в отличие от предыдущей версии Thumb, доступ ко всем ресурсам процессора. Предусмотрен доступ ко всем ARM-командам, введено и 12 полностью новых команд, улучшающих баланс «размер кода/производительность». Таким образом, Thumb-2 обеспечивает и повышенную производительность (процессор работает лишь на 2% медленнее, чем при использовании кода, компилированного с языка Си в код ARM-команд), и лучшую плотность кода (в среднем на четверть меньше, чем при использовании ARM-команд). По сравнению с Thumb, код Thumb-2 на 5% компактнее и на 2-3% быстрее. Нововведения упростили разработку программ и сделали ненужным совместное использование ARM- и Thumb-кода. Так, ядро Cortex-M, в отличие от ядер Cortex-A и Cortex-R, вообще поддерживает лишь набор команд Thumb-2.


Преимущества работы как в ARM-, так и в THUMB-режимах

(с командами THUMB-2)

 

  •  Нет необходимости переключаться между Thumb- и ARM-режимами кода, как в ранних вариантах реализации микроконтроллеров. Это позволило снизить временные потери;
  •  Thumb-2 разработан исключительно под язык программирования C, включая if/then конструкции, аппаратное деление и полноценный разрядный процессор;
  •  Новый набор команд позволяет эффективно использовать участки кода повторно, что позволяет создавать еще более плотный код;
  •  Инструкции Thumb-2 позволяют делать настолько эффективные компиляторы, что это дает возможность полностью отказаться от ассемблерных вставок;

В наборе команд Thumb-2 также предусмотрены улучшенные инструкции переходов, в т.ч. с проверкой и сравнением; блоки условного выполнения типа if/then и упорядочивание байт для обработки данных; а также инструкции извлечения байт или полуслов. Будучи RISC-процессором, ядро  Cortex обладает обширным набором команд, который специально разработан с учетом его использования Си-компилятором. Типичная программа для Cortex-M3 может быть полностью написана на ANSI Си с минимальным числом несовместимых с ANSI ключевых слов, за исключением таблицы векторов исключительных ситуаций, которую необходимо написать на Ассемблере.

Режимы работы

Несмотря на то, что процессор Cortex разрабатывался как быстродействующее, простое в использовании и с малым числом логических элементов микроконтроллерное ядро, в нем была учтена поддержка ОСРВ.

Процессор Cortex поддерживает два режима работы (рис. 8): режим Thread (или потоковый режим) и режим Handler (или режим обработчика). Ядро запускается в режиме Thread при непрерываемом, фоновом выполнении команд и переключается в режим Handler при обработке исключительных ситуаций. Кроме того, ядро Cortex может выполнять код программы в привилегированном или непривилегированном режиме. В привилегированном режиме, ядро имеет доступ ко всему набору команд, а в непривилегированном режиме некоторые инструкции отключаются (например, инструкции MRS и MSR, осуществляющие доступ к регистру xPSR и его битовым группам). В этом режиме также отключается доступ к большинству регистров управления системными ресурсами процессора Cortex. Также можно сконфигурировать использование стека. Основной стек (R13) может использоваться в обоих режимах Thread и Handler. Альтернативно, режим Handler можно настроить на использование стека процесса (банковый регистр R13).


Рис. 8.

Процессор Cortex-M3 может использоваться в обычном режиме ('flat'), а также поддерживает операционные системы реального времени. У него предусмотрены режимы Handler и Thread с возможностями выбора используемого стека (основной стек или стек процесса) и привилегированного доступа к регистрам управления системными ресурсами Cortex

Таблица 1.

 

Операции (после сброса - привилегированные)

Стек (после сброса - основной стек)

Режимы (Thread)

Handler
- обработка исключительных ситуаций

Привилегированное исполнение
Полное управление

Основной стек используется ОС и при обработке исключительных ситуаций

Thread
- исключительные ситуации не обрабатываются
- обычное выполнение кода

Привилегированные/ непривилегированные

Основной стек или стек процесса

Сразу после сброса процессор Cortex запускается в конфигурации 'flat'. В обоих режимах, Thread и Handler, инструкции выполняются в привилегированном режиме, т.о. какие-либо ограничения на доступ к процессорным ресурсам отсутствуют. В режимах Thread и Handler используется основной стек. Чтобы начать выполнение команд, достаточно указать процессору вектор сброса и стартовый адрес стека, после чего можно выполнять Си-код программы. Однако, если используется ОСРВ или выполняется разработка критичного к безопасности приложения, процессор может использоваться в более изощренной конфигурации: режим Handler (используется при обработке исключительных ситуаций и операционными системами реального времени) с привилегированными операциями и использованием основного стека и режим Thread при исполнении прикладного кода с непривилегированным доступом и использованием стека процесса. При таком подходе, весь код программы разделяется на системный и прикладной и, поэтому, ошибки в прикладном коде не вызывают сбоев ОСРВ.

Прерывания

Следующее нововведение архитектуры Cortex-M3 - это встроенный векторный контроллер вложенных прерываний (NVIC- Nested Vector Interrupt Controller).  

Контроллер, интегрированный в ядро Cortex-M3, может обеспечивать от 32 физических прерываний с 8 уровнями приоритета до 240 прерываний с 256 уровнями приоритета (в зависимости от реализации конкретным производителем микроконтроллера). Благодаря этому время входа в прерывание достаточно мало и всегда детерминировано, что позволяет использовать данные контроллеры в автомобильных и других ответственных приложениях реального времени.

NVIC использует стековую модель работы. Программный счетчик (program counter), регистр статуса программы (program status register), регистр связи (link register) и регистры общего назначения - все загружаются в стек при входе в обработчик прерываний. По выходе из обработчика содержимое регистров восстанавливается. Поэтому уже нет необходимости работать вручную со стеком в ассемблерном коде для сохранения данных на входе в обработчик прерываний и выходе из него.

Обработчики могут быть расставлены по приоритетам с целью обеспечения немедленного выполнения определенного прерывания, даже если в это время выполняется некое другое (с низшим приоритетом). Приоритеты могут меняться по необходимости в любом месте программы. Использование техники tail-chain позволяет не выполнять долговременные операции pop-push при последовательном выполнении нескольких прерываний, а просто при окончании цикла одного обработчика - «перепрыгивать» на начало следующего. И это занимает всего лишь 3 такта вместо 32 для полного цикла pop-push. Все это позволяет сократить задержки и увеличить производительность.

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

Обработка прерываний

Одними из главных усовершенствований ядра Cortex по сравнению с предшествующими ЦПУ ARM являются структура прерываний и механизм обработки исключительных ситуаций. ЦПУ ARM7 и ARM9 использовали две линии прерывания: быстродействующая линия прерывания и линия прерывания общего назначения. Данные линии поддерживали все источники прерываний в рамках микроконтроллера конкретного производителя. Однако, несмотря на использование казалось бы одинаковых подходов, конкретная реализация могла отличаться между разными производителями МК. Структуре прерываний ARM7 и ARM9 свойственны еще две проблемы. Во-первых, она недетерминистическая, т.к. время, которое требуется на завершение текущей инструкции при возникновении прерывания непостоянно. Конечно же, во многих приложениях это не создает проблем, но в системах реального времени могут возникнуть большие трудности. Во-вторых, поддержка вложенных прерываний в архитектуре ARM7 и ARM9 реализована неэффективно и требует написания дополнительных кодов программы в виде ассемблерных макросов или ОСРВ. Таким образом, ключевой задачей, которая стояла перед разработчиками ядра Cortex, являлась преодоление всех этих ограничений и разработка стандартной структуры прерываний, отличающейся предельным быстродействием и детерминистичностью.

Контроллер вложенных векторизованных прерываний

Контроллер вложенных векторизованных прерываний (КВВП) является стандартным блоком ядра Cortex (рис. 9). Это означает, что у любого Cortex-микроконтроллера будет присутствовать одна и та же структура прерываний, независимо от его производителя. Таким образом, прикладной код и операционные системы можно легко портировать с одного МК на любой другой и, при этом, программисту не потребуется изучение нового набора регистров. При разработке КВВП также учитывалось, что задержка реагирования на прерывание должна быть очень малой. Данная задача решена двояким образом: собственно возможностями КВВП, а также набором команд Thumb-2, многоцикловые инструкции которого, как например, инструкции многократного чтения/записи, являются прерываемыми. Задержка реагирования на прерывание то же является детерминистичной, что важно для систем реального времени. Как следует из наименования КВВП, им поддерживаются вложенные прерывания и, в частности, у МК STM32 используется 16 уровней приоритетов. Структура прерываний КВВП разработана с учетом программирования полностью на Си и исключает потребность в написании каких-либо ассемблерных макросов или специальных, несовместимых с ANSI, директив.


Рис. 9.

Несмотря на то, что КВВП является стандартным блоком ядра Cortex, в целях минимизации количества логических вентилей, разработчик МК может сконфигурировать количество линий прерываний, идущих к КВВП. Контроллер поддерживает одно немаскируемое прерывание и еще до 240 внешних линий прерывания, которые можно подключить к пользовательским УВВ. В ядре Cortex поддерживается еще 15 дополнительных источников прерываний, использующихся для обработки внутренних исключительных ситуаций ядра Cortex. Максимальное число маскируемых линий прерывания КВВП микроконтроллеров STM32 равно 43.

Работа КВВП при входе в исключительные ситуации и выходе из них

Если прерывание инициируется УВВ, то КВВП подключит ядро Cortex к обработке прерывания. После перехода ядра Cortex в режим прерывания, он помещает набор регистров в стек. Эта операция выполняется с помощью специального микрокода, что упрощает прикладной код. В процессе записи данных в стек на шине команд осуществляется выборка начального адреса процедуры обработки прерывания. Благодаря этому, с момента возникновения прерывания до выполнения первой инструкции его обработки проходит всего лишь 12 циклов (рис. 10).


Рис. 10.

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

К числу помещаемых в стек данных относятся регистр статуса программы, счетчик программы и регистр связи. Благодаря этому, запоминается состояние, в котором находилось ЦПУ Cortex CPU. Кроме того, также сохраняются регистры R0 - R3. Эти регистры широко используются в командах для передачи параметров, поэтому, помещение в стек делает возможным их использование в процедуре обработке прерывания. Замыкает список помещаемых в стек регистров - R12. Он выступает в роли рабочего регистра внутри подпрограммы. Например, если в компиляторе активизировать проверку стека, то будет генерироваться дополнительный код, который при потребности в регистре ЦПУ будет использовать R12. По завершении обработки прерывания все действия выполнятся в обратном порядке: с помощью микрокода извлекается содержимое стека и, параллельно с этим, осуществляется выборка адреса возврата, таким образом, для возобновления выполнения фоновой программы потребуется 12 циклов.

Улучшенные режимы обработки прерывания

Помимо высокого быстродействия обработки одного прерывания, КВВП также характеризуется эффективной обработкой нескольких прерываний, что важно для высокобыстродействующих систем реального времени. Для этого у КВВП поддерживается несколько оригинальных методов, позволяющие обрабатывать несколько запросов прерываний с минимальными задержками между прерываниями и с гарантированием приоритетности обработки прерываний.

Приостановка прерываний

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

Непрерывная обработка прерываний с исключением внутренних операций над стеком

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


Рис. 11.

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

Если возникает два прерывания, первым со стандартной задержкой в 12 циклов обслуживается прерывание с более высоким приоритетом. Однако, по окончании его обработки, ядро Cortex не возвращается к выполнению фоновой программы и содержимое стека не извлекается. Вместо этого, осуществляется выборка адреса процедуры обработки следующего прерывания с учетом приоритета. Таким образом, задержка перехода к обработке следующего прерывания составит всего лишь 6 циклов. По завершении обработки последнего прерывания извлекается содержимое стека и выполняется выборка адреса возврата. Таким образом, через 12 циклов возобновляется выполнение фоновой программы. Если же во время выхода из активного прерывания возникает еще одно низкоприоритетное прерывание, то операция извлечения из стека прекращается и указатель стека вернется к своему исходному значению, а выполнение обработки нового прерывания начнется через 6 дополнительных циклов (рис.12). В итоге, задержка вызова процедуры обработки нового прерывания будет в пределах 7-18 циклов.


Рис. 12.

Переход к обработке низкоприоритетного прерывания, которое возникает при выходе из текущего прерывания, выполняется с задержкой 7-18 циклов

Обработка опоздавшего высокоприоритетного прерывания

В системах реального времени часто возникают ситуации, когда во время перехода к обработке низкоприоритетного прерывания возникает еще одно прерывание с более высоким приоритетом. Если такая ситуация возникнет еще на фазе загрузки стека, то по его завершении КВВП инициирует переход к обработке высокоприоритетного прерывания. Загрузка стека будет продолжаться еще минимум 6 циклов с момента возникновения высокоприоритетного прерывания, после чего будет выполнена выборка нового адреса процедуры обработки прерывания (рис. 13).


Рис. 13.

Высокоприоритетное прерывание будет обработано первым, даже если оно возникнет уже на фазе перехода к обработке низкоприоритетного прерывания, при этом, дополнительные операции над стеком будут исключены

Отложенное низкоприоритетное прерывание будет обработано сразу по завершении обработки высокоприоритетного прерывания с задержкой 6 циклов.

Таблица векторов исключительных ситуаций

Таблица векторов Cortex начинается с нижней части адресного пространства. Однако таблица векторов начинается не с нулевого адреса, а с адреса 0x00000004, т.к. первые четыре байта используются для хранения начального адреса указателя стека.

Таблица векторов исключительных ситуаций содержит адреса, которые загружаются в счетчик программы, когда ЦПУ переходит в исключительную ситуацию

Каждый из векторов прерываний занимает 4 байта и указывает на начальный адрес каждой конкретной процедуры обработки прерывания. Первые 15 векторов - адреса обработки исключительных ситуаций, возникающих в ядре Cortex. К ним относятся вектор сброса, немаскируемое прерывание, управление авариями и ошибками, исключительные ситуации отладочной системы и прерывание таймера SysTick. Набором команд Thumb-2 также поддерживается команда, выполнение которой приводит к генерации исключительной ситуации. Начиная с 16 вектора, следуют адреса обработки прерываний пользовательских УВВ. Их назначение зависит от каждого конкретного производителя. В программе таблица векторов обычно приводится в отдельном файле и содержит адреса процедур обработки прерываний:

Когда сконфигурирована таблица векторов и объявлена процедура обработки прерываний, можно настроить КВВП на обработку прерывания таймера SysTick. Обычно, для этого выполняют две операции: задается приоритет прерывания, а затем разрешается источник прерывания.

Регистры КВВП находятся в области системных ресурсов Cortex-M3 и доступ к ним возможен при работе ядра только в привилегированном режиме.

Настройка внутренних исключительных ситуаций процессора Cortex выполняется с помощью регистров системного управления и системных приоритетов, а пользовательских УВВ - с помощью регистров IRQ.

Прерывание SysTick является внутренней исключительной ситуацией процессора Cortex и, поэтому, управляется через системные регистры.

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

Приоритет каждой внутренней исключительной ситуации Cortex можно задать в системных регистрах приоритета. У исключительных ситуаций Reset, NMI и hard fault он фиксированный. Этим гарантируется, что ядро всегда будет переходить к обработке известной исключительной ситуации. У всех остальных исключительных ситуаций имеется восьмиразрядное поле, которое расположено в трех системных регистрах приоритета.

Каждое пользовательское УВВ управляется через блоки регистров IRQ. У каждого такого УВВ имеется разряд разрешения прерывания. Все эти разряды находятся в пределах двух 32-разрядных регистров установки разрешения прерываний. Для отключения источника прерывания предусмотрены отдельные регистры отмены разрешения прерываний. У КВВП также имеются регистры отправленных и активных прерываний, которые позволяют отследить состояние источника прерывания.


Рис. 14.

У каждого источника прерывания имеется разряд разрешения, как в КВВП, так и в УВВ.

Всего предусмотрено 16 регистров приоритета. Каждый из них разделен на четыре 8-разрядных поля для задания приоритета. Каждое поле связано с конкретным вектором прерывания.

По умолчанию поле приоритета определяет 16 уровней приоритета, причем уровень 0 - наивысший приоритет, а 15 - наинизший.

Режимы сна

Схема управлением питанием ядра Cortex-M3 предусматривает следующие режимы энергосбережения:

Sleep Now,

Sleep on Exit (по выходу из последнего в очереди прерывания),

SLEEPDEEP режим.

Для удобства получения регулярного временного интервала NVIC содержит интегрированный системный таймер, который может быть использован как тактовый сигнал для операционных систем реального времени (RTOS) или как пробуждающий сигнал для выполнения очередных задач (scheduled tasks). Наличие этой возможности - одно из главных отличий от предыдущих ARM-архитектур.

Режимы работы, влияющие на энергопотребление

Процессор  Cortex поддерживает режим SLEEP, который переводит ядро Cortex в экономичный режим работы и приостанавливает выполнение команд. В этом состоянии частично продолжает работу КВВП, что позволяет возобновить работу ядра Cortex при генерации прерываний.

Переход в экономичный режим работы

Для перевода ядра Cortex в режим SLEEP необходимо выполнить инструкцию WFI (ожидание прерывания) или WFE (ожидание события). После выполнения инструкции WFI, ядро Cortex приостановит выполнение программы и обработку отправленных прерываний.

Существует два сценария завершения выполнения процедуры обработки прерывания. По первому сценарию ЦПУ выходит из процедуры обработки прерывания и возвращается к дальнейшему выполнению фоновой программы. Однако, если установить разряд SLEEPON EXIT в регистре системного управления, ядро Cortex после выхода из процедуры обработки прерываний автоматически перейдет в режим SLEEP. Такая возможность позволяет создавать управляемые прерываниями маломощные применения, в которых микроконтроллер после возобновления работы исполняет определенный код программы, а затем снова, не выполняя каких-либо команд для управления энергопотреблением, переходит в режим SLEEP.

Прерывание WFE позволяет возобновить работу ядра Cortex с того же места, с которого оно было переведено в режим SLEEP. Это прерывание не приводит к переходу к процедуре обработки прерывания. Возобновляющее работу событие - это обычная линия прерывания УВВ, но которая на активизирована как прерывание в КВВП. Благодаря этому, УВВ может сигнализировать ядру Cortex о необходимости возобновления работы и продолжения обработки, не прибегая к использованию процедуры обработки прерывания. Инструкции WFI и WFE не поддерживаются языком Си, однако компиляторы для набора команд Thumb-2 поддерживают встроенные макросы, которые можно использовать в программе, как стандартные Си-команды:

__WFI

__WFE

Помимо экономичных режимов работы SLEEPNOW и SLEEPONEXIT, ядро Cortex может генерировать сигнал SLEEPDEEP для остальной части микроконтроллерной системы.


Рис. 15.

Регистр системного управления конфигурирует режимы SLEEP процессора Cortex.

Системный таймер

В ядро Cortex входит 24-разрядный вычитающий счетчик с функциями автоматической перезагрузки и генерации прерывания. Он называется таймером SysTick и предназначен для использования в качестве стандартного таймера во всех Cortex-микроконтроллерах. Таймер SysTick может использоваться для формирования шкалы времени в ОСРВ или для генерации периодических прерываний для обработки запланированных задач. С помощью регистра управления и статуса таймера SysTick, который расположен в области системных ресурсов процессора Cortex-M3, пользователь может выбрать источник синхронизации таймера. Если установить разряд CLKSOURCE, то таймер SysTick будет работать на тактовой частоте ЦПУ. Если же его сбросить, то таймер будет работать на частоте, равной 1/8 тактовой частоты ЦПУ.

Таймер SysTick - 24-разрядный автоматически-перезагружаемый таймер, являющийся частью процессора Cortex-M3. Он предназначен для формирования шкалы времени в операционных системах реального времени

У таймера SysTick имеется три регистра. Для задания периодичности счета необходимо инициализировать регистр текущего значения и регистр перезагружаемого значения. В регистре управления и статуса имеются разряды ENABLE, позволяющий активизировать работу таймера, и TICKINT, управляющий активностью линии прерывания таймера. Далее мы будем рассматривать структуру прерываний Cortex и использование таймера SysTick для генерации первой исключительной ситуации в микроконтроллере STM32.

Отладочная система CoreSight

У всех ядер ARM имеется собственная встроенная отладочная система. Ядра ARM7 и ARM9, как минимум, имеют порт JTAG, который является стандартным интерфейсом для подключения к ЦПУ, а также загрузки кода программы во внутреннее ОЗУ или Flash память. Порт JTAG также поддерживает базовые функции управления исполнением программы (пошаговое выполнение, установка контрольных точек и др.) и делает возможным просмотр содержимого ячеек памяти. С помощью специального блока, который называется встроенной трассировочной макроячейкой (ETM), ядро ARM7 и ARM9 также предоставляют возможности трассировки в масштабе реального времени. Несмотря на то, что данная отладочная система работает отлично, она имеет некоторые ограничения. Когда ядро ARM остановлено, связанная с портом JTAG отладочная система, способна предоставлять только отладочную информацию и не имеет возможностей обновления в реальном времени. Кроме того, количество аппаратных контрольных точек ограничено двумя. Из-за этого в наборы команд ARM7 и ARM9 включены инструкции контрольных точек, которые отладочное средство может вставлять в код программы (обычно они называются программными контрольными точками). Наконец, чтобы появилась поддержка реально-временной трассировки, производитель должен в ущерб стоимости микроконтроллера интегрировать в него ETM. В итоге, в микроконтроллерах такой поддержки чаще всего не оказывается. В новом ядре Cortex применена абсолютно иная отладочная система, которая получила название CoreSight.

Процессорные ядра ARM Cortex-M

Семейство ARM Cortex-M – совместимые снизу вверх энергоэффективные, простые в применении процессорные ядра, призванные помочь разработчикам выполнять требования будущих встраиваемых приложений, т.е. позволяющие предоставлять больше функций при меньшей стоимости, увеличить возможности взаимодействия, улучшить повторное использование кода и обеспечить энергоэффективность. Каждое процессорное ядро серии Cortex-M имеет свои специфические достоинства, но все выполнены на основе фундаментальной технологии, благодаря которой они перспективны для большого ряда встраиваемых приложений.

Процессорные ядра подсемейства Cortex-M находят применение в микроконтроллерах и устройствах смешанной обработки сигнала, применяемых в интеллектуальных измерительных приборах, пользовательских интерфейсах, автомобильных и промышленных системах управления, предметах домашнего обихода, бытовой технике и медицинском оборудовании, к характеристикам которых предъявляются специфические требования.

Сortex-M3 – первое процессорное ядро, которое и дало имя семейству Cortex, было представлено потребителям в 2004 году. При создании Сortex-M3 ставилась задача замены ядра ARM7TDMI, которое использовалось во множестве высокопроизводительных микроконтроллеров.

Основа 32-разрядного Сortex-M3 процессора — ядро с Гарвардской архитектурой и трехступенчатым конвейером, что обеспечивает предсказание переходов, однотактное умножение и аппаратно реализуемое деление. Неотъемлемые элементы архитектуры Сortex-M3 — блок вложенных прерываний, отладочная система и предопределенная организация памяти (рис.1).

Рис.1. Блок-схема Cortex-M3 процессора

При создании ядра Сortex-M3 в базовую ARM-архитектуру было внесено множество изменений. Так, компания отказалась от ARM-режима, тогда как все предыдущие ядра имели два режима работы – ARM и Thumb, каждый с набором 32- и 16-разрядных инструкций, соответственно.

У Сortex-M3 предусмотрена поддержка набора ARM Thumb-2 инструкций. При этом в набор Thumb-2 внесено 130 дополнительных команд. Thumb-2 позволяет добиться плотности кода, свойственной 16-разряд набору инструкций Thumb, т.е. получить в среднем выигрыш в 20–30% по сравнению с 32-разряд ARM-набором при снижении производительности всего на единицы процентов. Исключается необходимость переключения между режимами ARM и Thumb, что позволяет обойтись без блока переключения. Процессоры с набором инструкций Thumb-2 способны создавать код намного быстрее, проще и эффективнее, чем при работе с ARM-набором инструкций.

Важное нововведение в Cortex-M3 – возможность аппаратного выполнения операции деления. (До появления семейства Cortex в ARM-ядрах предусматривались операции умножения и умножения с накоплением с 64-разряд результатом.) И хотя операция деления занимает немало тактов процессорных ядер, она выполняется быстрее, чем отдельная подпрограмма. Кроме того, Cortex-М3 может оперировать с невыровненными данными (unaligned data), что также отличает его от предшествующих архитектур ARM и поддерживает разрядовые операции (bit banding).

Еще один ключевой компонент ядра Cortex-M3 – контроллер векторизованных вложенных прерываний (КВВП), предоставляющий для всех Cortex-микроконтроллеров стандартную структуру прерываний и способы их обработки. Конфигурируемое ядро Cortex-M3 соединяется с периферией посредством шины Advanced High-PerformanceBus (AHB), что позволяет разработчику с легкостью подключать к нему собственные подсистемы.

Благодаря этим нововведениям применение процессорных ядер Cortex-М3 стало рентабельным даже в самых простых приложениях.

 Cortex-M1 – процессорное ядро, разработанное в начале 2007 года (рис.2) и оптимизированное для реализации в FPGA.

Рис.2. Блок-схема Cortex-M1 процессора

Ядро предназначено для применения во всех основных FPGA-платформах. В нем предусмотрена поддержка ведущих средств синтеза FPGA, что позволяет проектировщику выбирать оптимальную конструкцию проекта. Cortex-M1 поддерживает трехстадийную 32-разрядную очередь команд и работает с несколько модифицированным набором команд Thumb-2. Микропроцессорное ядро способно исполнять и код Thumb и таким образом будет программно совместимо с ARM7TDMI. Cortex-M1 обеспечивает существенную экономию затрат за счет рационализации расходов на программное обеспечение и инструментарий для многих проектов по созданию FPGA, ASIC и ASSP-микросхем. При этом благодаря применению стандартизированного в промышленности процессорного ядра разработчики систем все меньше зависят от поставщика требуемых компонентов.

Рабочая частота процессора на основе ядра Cortex-M1 и занимаемая им площадь зависят от используемой FPGA-платформы. Для FPGAProASIC3 и Actel Fusion, изготавливаемых по 130-нм технологии, эти параметры лежат в пределах от 70 МГц и 4300 логических ячеек, соответственно.

Для FPGA Stratix-III и Virtex-5 компаний Altera и Xilinx, изготавливаемых по 65-нм технологии, — до 200 МГц и 1900 логических ячеек. Производительность Cortex-M1 при частоте 170 МГц составляет 0,8 DMips/МГц (производительность по эталонному тесту Dhrystone).

Основные области применения Cortex-M1 – контрольно-измерительные встраиваемые системы, сетевое и телекоммуникационное оборудование.

Cortex-M0 (рис.3) ядро подсемейства Cortex-M, обеспечивающее самые малые размеры, самую низкую мощность и самое большое энергосбережение процессора, появилось в начале 2009 года.

.

Рис.3. Блок-схема Cortex-M0 процессора

Cortex-M0 процессор, выполненный по сверхмаломощной универсальной технологии TSMC потребляет всего 85 мкВт/МГц, занимая площадь менее 12 тыс. логических вентилей. Малое энергопотребление, небольшое число логических вентилей и компактный код, по словам разработчика, позволяют создать 32-разрядный процессор по цене 8-разрядного изделия. Важным достоинством с точки зрения экономии средств является совместимость с Cortex-M3 на уровне инструментов разработки и бинарных файлов.

Cortex-M0 найдет применение в устройствах, которые  привыкли видеть вокруг себя каждый день. Это медицинская аппаратура, электронные счетчики, системы освещения и управления, игровые устройства, компактные источники питания, регуляторы мощности и блоки управления электроприводами, аналоговые устройства повышенной точности и сетевое оборудование IEEE 802.15.4 (ZigBee) и Z-Wave. Стоит отметить и возможность применения Cortex-M0 в инструментах, содержащих как аналоговые, так и цифровые элементы, например в «умных» датчиках и исполнительных механизмах.

Cortex-M4 (рис.4). Это встраиваемое процессорное ядро компания ARM представила в феврале 2010 года.

Рис.4. Блок-схема Cortex-M4 процессора

Ядро разработано для систем, требующих простое в применении устройство, сочетающее функции управления и цифровой обработки сигнала. Cortex-M4 отличается поддержкой однотактной операции умножения с запоминанием за один такт и оптимизированной арифметики.

Площадь Cortex-M4 процессора, его частота и потребляемая мощность зависят от технологического процесса изготовления, используемой библиотеки элементов и параметра, по которому он оптимизирован (быстродействие или размер).

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

Архитектура  IA-64

Использование принципа явного параллелизма

Архитектура IA-64 коренным образом отличается от архитектуры IA-32. Основная концепция архитектуры IA-64 - это параллелизм на уровне команд, или явный параллелизм.

Для увеличения числа команд, выполняемых за такт  и обеспечения высокой производительности, разработчики процессоров с архитектурой типа IA-32 вынуждены были использовать различные аппаратные ухищрения, такие, как:

внутреннее разбиение CISC-команд на простые RISC-команды;

использование большого  регистрового файла, несмотря на то, что программисту может быть доступна только малая его часть. Например, в одном из процессоров линии Pentium регистровый фал состоит из 40 регистров при доступных программисту 8 регистрах.

динамическое выполнение команд в порядке отличном от предписанного в программе;

предсказание переходов и предположительное  исполнение;

предвыборка данных и т. п.

Все заботы на обеспечение максимально возможного параллелизма при выполнении программы возлагаются на аппаратуру процессора. Чем больше параллелизма пытаются реализовать разработчики аппаратуры, тем сложнее устройство управления для разработки, тем больше необходимо тратить   ресурсов, причем, зависимость затрат от степени увеличения параллелизма существенно нелинейная. Даже в лучших современных процессорах удается выполнять за один такт не более 4 – 6 команд. Возможности аппаратуры ограничены малым окном просмотра.

Архитектура IA64 переложила управление этими задачами на компилятор. В его задачи входит анализ программы и выявление максимально возможного параллелизма. Возможности компилятора при этом практически не ограничены. Он может иметь окно просмотра необходимого размера без  ограничений, свойственных аппаратному походу.

Основные особенности архитектуры IA-64 следующие:

команды в формате IA-64 упакованы по три в 128-битный пакет для быстрейшей обработки. В любом случае формат команд IA-64 не имеет ничего общего с х86. Команды х86 могут иметь длину от 8 до 108 бит, и процессор должен последовательно декодировать каждую команду после определения её границ.

каждый 128-битный пакет содержит шаблон (template) длиной в несколько бит, помещаемый в него компилятором, который указывает процессору, какие из команд могут выполняться параллельно. Теперь процессору не нужно будет анализировать поток команд в процессе выполнения для выявления "скрытого параллелизма". Вместо этого наличие параллелизма определяет компилятор и помещает информацию в код программы. Каждая команда (как для целочисленных вычислений, так и для вычислений с плавающей точкой) содержит три 7-битных поля регистра общего назначения (РОН).По сравнению с процессорами х86, у которых всего восемь целочисленных РОН и стек глубины 8 для вычислений с плавающей точкой, IA-64 намного "шире" и, соответственно, будет намного реже простаивать из-за "нехватки регистров".

Компиляторы для IA-64 используют технологию "отмеченных команд" (predication) для устранения потерь производительности из-за неправильно предсказанных переходов и необходимости пропуска участков кода после ветвлений. Когда процессор встречает "отмеченное" ветвление в процессе выполнения программы, он начинает одновременно выполнять все ветви. После того, как будет определена "истинная" ветвь, процессор сохраняет необходимые результаты и сбрасывает остальные.

Компиляторы для IA-64 будут также просматривать исходный код с целью поиска команд, использующих данные из памяти. Найдя такую команду, они будут добавлять пару команд - команду предварительной загрузки (speculative loading) и проверки загрузки (speculative check). Во время выполнения программы первая из команд загружает данные в память до того, как они понадобятся программе. Вторая команда проверяет, успешно ли произошла загрузка, перед тем, как разрешить программе использовать эти данные. Предварительная загрузка позволяет уменьшить потери производительности из-за задержек при доступе к памяти, а также повысить параллелизм.

Из всего вышесказанного следует, что компиляторы для процессоров архитектуры IA-64 должны быть намного "умнее" и лучше знать структуру  процессора, код для которого они вырабатывают. Существующие микросхемы процессоров, в том числе и RISC-процессоры, производят гораздо больше оптимизации на этапе выполнения программ, даже при использовании оптимизирующих компиляторов. IA-64 перекладывает практически всю работу по оптимизации потока команд на компилятор. Таким образом, программы, скомпилированные для одного поколения процессоров архитектуры IA-64, на процессорах следующего поколения без перекомпиляции могут выполняться неэффективно. Это ставит перед разработчиками и поставщиками программного обеспечения нелёгкую задачу по выпуску нескольких версий исполняемых файлов для достижения максимальной производительности.

Другим, не очень приятным следствием, будет увеличение размеров кода, так как команды IA-64 длиннее, чем 32-битные стандартные RISC-команды. Компиляция при этом будет занимать больше времени, поскольку IA-64, как уже было сказано, требует от компилятора гораздо больше действий.  Насколько это существенно? Относительно увеличения времени компиляции, то опасения об увеличения  несерьезны в большинстве случаев. Компиляция выполняется на этапе разработки приложений и не является критическим интервалом во всем периоде разработки. Даже если время компиляции увеличится в несколько раз, это не скажется на времени выполнения приложения. Об увеличении длины команды по сравнению со стандартными RISC-архитектурами можно утверждать следующее. В настоящее время стоимость бита оперативной памяти достаточно малая, а в будущем она еще  больше будет уменьшаться. Поэтому, ради упрощения аппаратуры процессора, увеличения производительности ВС целесообразно принимать решения об увеличении разрядности команды.

Технология "отмеченных команд" является наиболее характерным примером "дополнительной ноши", перекладываемой на компиляторы. Эта технология является центральной для устранения ветвлений и управления параллельным выполнением команд.

Обычно компилятор транслирует оператор ветвления (например, IF-THEN-ELSE) в блоки машинного кода, расположенные последовательно в потоке. В зависимости от условий ветвления процессор выполняет один из этих блоков и перескакивает через остальные. Современные процессоры стараются предсказать результат вычисления условий ветвления и предварительно выполняют предсказанный блок. При этом в случае ошибки много тактов тратится впустую. Сами блоки зачастую весьма малы - две или три команды, - а ветвления встречаются в коде в среднем каждые шесть команд. Такая структура кода делает крайне сложным его параллельное выполнение.

Когда компилятор для IA-64 находит оператор ветвления в исходном коде, он исследует ветвление, определяя, стоит ли его "отмечать". Если такое решение принято, компилятор помечает все команды, относящиеся к одному пути ветвления, уникальным идентификатором, называемым предикатом (predicate). Например, путь, соответствующий значению условия ветвления TRUE, помечается предикатом Р1, а каждая команда пути, соответствующего значению условия ветвления FALSE - предикатом Р2. Система команд IA-64 определяет для каждой команды 6-битное поле для хранения этого предиката. Таким образом, одновременно могут быть использованы 64 различных предиката. После того, как команды "отмечены", компилятор определяет, какие из них могут выполняться параллельно. Это опять требует от компилятора знания архитектуры конкретного процессора, поскольку различные чипы архитектуры IA-64 могут иметь различное число и тип функциональных узлов. Кроме того, компилятор, естественно, должен учитывать зависимости в данных (две команды, одна из которых использует результат другой, не могут выполняться параллельно). Поскольку каждый путь ветвления заведомо не зависит от других, какое-то "количество параллелизма" почти всегда будет найдено.

Заметим, что не все ветвления могут быть отмечены: так, использование динамических методов вызова приводит к тому, что до этапа выполнения невозможно определить, возникнет ли исключение. В других случаях применение этой технологии может привести к тому, что будет затрачено больше тактов, чем сэкономлено.

После этого компилятор транслирует исходный код в машинный и упаковывает команды в 128-битные пакеты, шаблон пакета (bundle's template field) указывает не только на то, какие команды в пакете могут выполняться независимо, но и какие команды из следующего пакета могут выполняться параллельно. Команды в пакетах не обязательно должны быть расположены в том же порядке, что и в машинном коде, и могут принадлежать к различным путям ветвления. Компилятор может также помещать в один пакет зависимые и независимые команды, поскольку возможность параллельного выполнения определяется шаблоном пакета. В отличие от некоторых ранее существовавших архитектур со сверхдлинными словами команд (VLIW), IA-64 не добавляет команд "нет операции" (NOPS) для дополнения пакетов.

Во время выполнения программы IA-64 просматривает шаблоны, выбирает взаимно независимые команды и распределяет их по функциональным узлам. После этого производится распределение зависимых команд. Когда процессор обнаруживает "отмеченное" ветвление, вместо попытки предсказать значение условия ветвления и перехода к блоку, соответствующему предсказанному пути, процессор начинает параллельно выполнять блоки, соответствующие всем возможным путям ветвления. Таким образом, на машинном уровне ветвления нет.

Разумеется, в какой-то момент процессор наконец вычислит значение условия ветвления в нашем операторе IF-THEN-ELSE. Предположим, оно равно TRUE, следовательно, правильный путь отмечен предикатом Р1. 6-битному полю предиката соответствует набор из 64 предикатных регистров (predicate registers) Р0-Р63 длиной 1 бит. Процессор записывает 1 в регистр Р1 и 0 во все остальные.

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

Технология "отмеченных команд" существенно снижает негативное влияние ветвлений на машинном уровне. В то же время, если компилятор не "отметил" ветвление, IA-64 действует практически так же, как и современные процессоры: пытается предсказать путь ветвления и т.д. Испытания показали, что описанная технология позволяет устранить более половины ветвлений в типичной программе, и, следовательно, уменьшить более чем в два раза число возможных ошибок в предсказаниях.

Другой ключевой особенностью IA-64 является предварительная загрузка данных. Она позволяет не только загружать данные из памяти до того, как они понадобятся программе, но и генерировать исключение только в случае, если загрузка прошла неудачно. Цель предварительной загрузки - разделить собственно загрузку и использование данных, что позволяет избежать простоя процессора. Как и в технологии "отмеченных команд" здесь также сочетается оптимизация на этапе компиляции и на этапе выполнения.

Сначала компилятор просматривает код программы, определяя команды, использующие данные из памяти. Везде, где это возможно, добавляется команда предварительной загрузки на достаточно большом расстоянии перед командой, использующей данные и команда проверки загрузки непосредственно перед командой, использующей данные.

На этапе выполнения процессор сначала обнаруживает команду предварительной загрузки и, соответственно, пытается загрузить данные из памяти. Иногда попытка оказывается неудачной - например, команда, требующая данные, находится после ветвления, условия которого ещё не вычислены. "Обычный" процессор тут же генерирует исключение. IA-64 откладывает генерацию исключения до того момента, когда встретит соответствующую команду проверки загрузки. Но к этому времени условия ветвления, вызывавшего исключение, уже будут вычислены. Если команда, инициировавшая предварительную загрузку, относится к неверному пути, загрузка признается неудачной и генерируется исключение. Если же путь верен, то исключение вообще не генерируется. Таким образом, предварительная загрузка в архитектуре IA-64 работает аналогично структуре типа TRY-CATCH.

Возможность располагать команду предварительной загрузки до ветвления очень существенна, так как позволяет загружать данные задолго до момента использования (каждая шестая команда является командой ветвления).

Поддержка режима IA-32

IA-64 предусматривает полную программную совместимость с IA-32, но, к сожалению, скорость исполнения 32-битного кода в процессорах оставляет желать лучшего. Инструкции IA-32 аппаратно преобразуются в последовательности команд IA-64, которые исполняются медленно из-за отсутствия оптимизации под архитектуру и аппаратных ухищрений исполнения кода. Запускать на процессоре имеет смысл только те 32-битные приложения, которые не критичны к скорости исполнения.

Связка  команд

Наиболее кардинальным нововведением IA-64 по сравнению с RISC является "явный параллелизм команд (EPIC - Explicitly Parallel Instruction Computing), привносящий в IA-64 некоторые элементы, напоминающие архитектуру "сверхбольшого командного слова" (VLIW - Very Large Instruction Word). В обеих архитектурах явный параллелизм представлен уже на уровне команд, управляющих одновременной работой функциональных исполнительных устройств (ФИУ). Соответствующие "широкие команды" HP/Intel назвали связками (bundle).

Рис. 1. Формат связки команд IA-64

Связка имеет длину 128 разрядов (рис.1). Она включает 3 поля - "слота" для команд длиной 41 разрядов каждая, и 5-разрядное поле шаблона. Предполагается, что команды связки могут выполняться параллельно разными ФИУ. Возможные взаимозависимости, препятствующие параллельному выполнению команд связки, отражаются в поле шаблона. Параллельно могут выполняться и команды разных связок. Шаблон указывает, какого типа команды находятся в слотах связки. В общем случае команды одного типа могут выполняться в более чем одном типе ФИУ (табл.1). Шаблоном задаются так называемые остановки, определяющие слот, после начала выполнения команд которого команды последующих слотов должны ждать завершения. Порядок слотов в связке (возрастание справа налево) отвечает и порядку байт - little endian. Однако данные в памяти могут располагаться и в режиме big endian. Режим устанавливается специальным разрядом в регистре маски пользователя.

Последовательность команд от остановки до остановки (или выполняемого перехода) называется группой команд. Она начинается с заданного адреса команды (адрес связки плюс номер слота) и включает все последующие команды - с увеличением номера слота в связке, а затем и адресов связок, пока не встретится остановка.

Таблица 1. Типы команд и исполнительных устройств

Тип команд

Тип исполнительного устройства

Описание команд

A

I или M

Целочисленные, АЛУ

I

I

Целочисленные неарифметические

M

M

Обращение в память

F

F

C плавающей запятой

B

B

Переходы

L+X

I

Расширенные

Регистры общего назначения

В их число входят: 128 регистров общего назначения GR; 128 регистров с плавающей запятой FR; 64 регистра предикатов PR; 8 регистров перехода BR; 128 прикладных регистра AR; не менее 4 регистров идентификатора процессора CPUID; cчетчик команд IP, указывающий на адрес связки, содержащей исполняемую команду; регистр маркера текущего окна CFM, описывающий окно стека регистров и др.

Регистры CPUID являются 64-разрядными. В CPUID-регистрах 0 и 1 лежит информация о производителе, в регистре 2 находится серийный номер процессора, а в регистре 3 задается тип процессора (cемейство, модель, версия архитектуры и т.п.) и число CPUID-регистров. Разряды регистра 4 указывают на поддержку конкретных особенностей IA-64, т.е. тех, которые реализованы в данном процессоре.

Прикладные регистры AR0-AR127 - специализированные (в основном 64-разрядные) регистры, применяемые в IA-64 и IA-32. AR0-7 называются регистрами ядра; запись в них привилегирована, но они доступны на чтение в любом приложении и используются для передачи приложению сообщений от операционной системы.

Среди других прикладных регистров необходимо отметить:

AR16 (RSC) - регистр конфигурации стека регистров, используемый для управления работой "машиной" стека регистров IA-64 (RSE);

AR17 (BSP), в котором находится адрес в памяти, где сохраняется положение GR32 в текущем окне стека;

AR40 (FPSR) - регистр состояния для команд с плавающей запятой IA-64;

AR44 (ITC) - интервальный таймер;

AR64 (PFS) - регистр предыдущего состояния функции, куда автоматически копируются некоторые другие регистры при вызове подпрограмм;

AR65 (LC), используемый для организации циклов со счетчиком;

AR66 (EC) - 6-разрядный регистр эпилога .

Ряд AR-регистров является фактически регистрами IA-32 (дескриптор сегмента кодов, дескриптор сегмента стека и др.).

64-разрядные регистры GR0-127 применяются не только для целочисленных операций IA-64; GR8-31 в режиме IA-32 используются также под целочисленные регистры и регистры селекторов и дескрипторов сегментов IA-32. GR0-31 называются статическими регистрами (GR0 всегда содержит 0), а GR32-127 - стекируемыми регистрами. Статические регистры "видны" всем программам. Стекируемые регистры становятся доступными в программной единице через окно стека регистров, включающее локальные и выходные регистры, число которых задается командой alloc.

Контрольные вопросы

  1.  Какие причины обусловили появление архитектуры IA-64?
  2.  В чем суть принципа явного параллелизма?
  3.  Назовите основные особенности архитектуры IA-64
  4.  Какие требование предъявляются к компиляторам для программ с архитектурой IA-64?
  5.  Какое количество регистров предусмотрено в архитектуре IA-64?
  6.  Каким образом в пакете команд указывается последовательность выполнения команд?

Архитектура IA-64. Программная модель. Система команд

Регистры для чисел с плавающей запятой

82-разрядные регистры с плавающей запятой FR0-127 также подразделяются на статические (FR0-31, причем всегда FR0=0.0, FR1=1.0) и вращаемые (FR32-127). FR8-31 в режиме IA-32 содержат числа с плавающей запятой и мультимедийные регистры.

Вращение регистров является в некотором роде частным случаем переименования регистров, применяемого во многих современных суперскалярных процессоров с внеочередным спекулятивным выполнением команд. В отличие от них, вращение регистров в IA-64 управляется программно.

Предикатные регистры

64-разрядные регистры переходов BR0-7 применяются для указания адреса перехода в соответствующих командах перехода (если адрес перехода не кодируется в команде явно). Регистры предикатов PR0-63 являются одноразрядными; в них помещаются результаты команд сравнения. Обычно эти команды устанавливают сразу два регистра PR в зависимости от условия - соответственно истинность условия и его отрицания. Такая избыточность обеспечивает дополнительную гибкость. PR0-15 являются статическими (PR0 всегда равен 1), а PR16-63 - вращаемыми. Статические предикатные регистры используются в командах условного перехода. Кроме того, почти все команды IA-64 могут быть выполнены "под предикатом".

Работа стека регистров

Файл регистров GR отличается от FR и PR тем, что последние содержат фиксированные подмножества статических и вращаемых регистров, в то время как в файле GR вне подмножества статических регистров применяется стек регистров, и программной единице доступна лишь его часть - окно стека регистров. В отличие от статических регистров, стекируемое подмножество локально для любой программной единицы и может иметь размер от 0 до 96 регистров, начиная с GR32.

Использование этого механизма в IA-64 позволяет, как мы увидим, избежать накладных расходов, связанных с сохранением/восстановлением большого числа регистров при вызовах подпрограмм и возвратах из них (однако статические регистры при необходимости все-таки приходится сохранять и восстанавливать, явно кодируя соответствующие команды). Автоматическое сохранение/восстановление стекируемого подмножества регистров осуществляет RSE, и в программе об этом заботиться не надо. В режиме IA-32 работа с этим стеком регистров, естественно, отключается.

До сих пор не рассматривался один из важнейших регистров IA-64 - 38-разрядный регистр CFM, в котором как раз сохраняется состояние "текущего" окна стека регистров. Как и другие маркеры окна, CFM содержит общий размер окна стека, число локальных регистров и (кратное 8) число вращаемых регистров в окне, а также 3 значения базы для переименования регистров - соответственно rrb.gr, rrb.fr и rrb.pr.

Итак, окно стека имеет две области переменного размера - локальную и выходную. Рассмотрим вызов процедур подробнее. При переходе типа "вызов процедуры" CFM вызывающей подпрограммы сохраняется в поле PFM (Previous Frame Marker) регистра PFS, и создается CFM вызываемой подпрограммы. Сразу после вызова размер локальной области вызываемой подпрограммы равен размеру выходной области вызывающей и перекрывается с ней. При этом стекируемые регистры автоматически переименовываются таким образом, что первый регистр выходной области вызывающей подпрограммы становится регистром GR32 вызываемой (рис.1, где procA - это вызывающая, а procB - вызываемая подпрограмма). Перекрытие их выходных областей позволяет эффективно передавать параметры через регистры.

Рис. 1. Стек регистров при вызове procB из procA

Как уже указывалось ранее, вызываемая подпрограмма может изменить размеры своих локальной и выходной областей командой alloc; cоответствующим образом будут изменены и поля в CFM. Команда alloc обычно используется вызываемой подпрограммой для того, чтобы распределить себе определенное число локальных регистров и заиметь выходную область для передачи параметров уже собственному "потомку". Если запрошенное в команде alloc количество регистров оказывается недоступным (переполнение стека), alloc приостанавливает процессор и RSE будет сохранять регистры вызывающей подпрограммы, пока запрошенное alloc число регистров не будет доступным.

При переходе типа "возврат из процедуры" CFM восстанавливается из PFM, а обратное переименование регистров восстанавливает состояние вызывающей подпрограммы. Если некоторые ее регистры были ранее "сброшены" RSE, то при возврате RSE приостановит процессор до тех пор, пока не будут восстановлены эти регистры.

Система команд IA-64

 

В этом разделе дается краткий обзор системы команд IA-64, а точнее, ее "непривилегированной части". Именно это подмножество команд определяет наиболее принципиальные особенности IA-64. Cреди этих принципиальных особенностей следует особо отметить спекулятивное (по предположению) выполнение команд и применение предикатов.

Все рассматриваемые команды можно подразделить на:

 - команды работы со стеком регистров (например, alloc);

- целочисленные команды; команды сравнения и работы с предикатами;

- команды доступа в память;

 - команды перехода;

- мультимедийные команды;

 - команды пересылок между регистрами;

- "разные" (операции над строками и подсчет числа единиц в слове);

-  команды работы с плавающей запятой.

Целочисленные команды IA-64 включают арифметические операции (add, sub и др.), логические операции (and, or, xor и др.), операции над битами и сдвиги, а также 32-разрядные операции. Большинство этих команд трехадресные, а их аргументы лежат в регистрах; однако встречается и литеральное представление аргументов. Имеются также модификации команд add и sub, которые являются четырехадресными: в них к сумме/разности регистров прибавляется/вычитается 1.

Отметим, что команда умножения целых чисел в регистрах GR отсутствует; для перемножения необходима пересылка целых в регистры FR и применение операции умножения, выполняемой в ФИУ вещественного типа. Некоторые специалисты считают это "наименее удачной" чертой системы команд IA-64.

Команды сравнения и работа с предикатами - это одна из принципиально новых особенностей IA-64 по сравнению с RISC-архитектурой. Приведем сначала несколько типичных примеров команд этой группы. Команда cmp сравнивает два регистра GR (или регистр GR и литерал) на одно из 10 возможных условий (больше, меньше или равно и т.п.). Команда tbit тестирует заданный бит GR. Команда fcmp сравнивает два числа с плавающей запятой. Однако результатом сравнения является не единственный код условия, что типично для обычных процессоров. Логический результат сравнения (1 - истина, 0 - ложь) записывается обычно в пару предикатных регистров (во второй пишется отрицание первого).

Эти значения предикатных регистров используются затем не только в командах условного перехода, как в обычных микропроцессорах. Почти все команды IA-64 выполнимы "под предикатом", т.е. могут выполняться или нет в зависимости от значения указанного в команде PR-регистра. Это позволяет во многих случаях избежать применения условных переходов, которые, как известно, отрицательно сказываются на производительности микропроцессоров. Вместо этого процессор c архитектурой IA-64, имеющий большое число ресурсов (в частности, регистров и ФИУ), может исполнить обе ветви программы. Рассмотрим простейший пример 1.

Спекулятивное (по предположению) выполнение

Команды доступа в память. Прежде всего, это команды загрузки регистров и записи из них в оперативную память. Команда Ld загружает в GR 1-, 2-, 4- и 8-байтные целочисленные величины; аналогично ldf загружает в FR числа с плавающей запятой размером 4, 8, 10 байт, а также пары 4-байтных чисел. В этих командах можно указать также на тонкие особенности работы с оперативной памятью и кэшем. Имеются и специальные команды работы с кэшем.

Принципиальной является возможность кодирования указанных команд загрузки в специальных спекулятивных формах. Различают загрузку спекулятивную по управлению и спекулятивную по данным.

Спекулятивное по управлению выполнение означает возможность заранее выполнить команды, расположенные за командой условного перехода, до того, как будет известно, будет ли осуществляться этот условный переход на соответствующую ветвь программы. При наличии большого числа ресурсов процессора это позволяет заранее запускать на выполнение команды, которые начнут выполняться одновременно с уже начавшими выполняться другими командами (в других ФИУ). Однако позднее может выясниться, что эти спекулятивно выполненные команды оказались выполненными напрасно, так как переход на эту ветвь не произошел, и нужно произвести "откат".

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

Все команды можно разделить на спекулятивно выполнимые и спекулятивно невыполнимые. Последние могут вызывать прерывания, которые не могут быть отложены. Обычные вычислительные команды, имеющие GR или FR в качестве регистров результата, - спекулятивные. Если же команда изменяет другие типы регистров, она не спекулятивная.

Кроме обычных не спекулятивных команд (Ld, Ldf...) в IA-64 имеются их спекулятивные модификации (ld.s, ldf.s...). Вычислительные команды в общем случае не вызывают прерываний (операции с плавающей запятой обрабатывают прерывания специальным образом), поэтому единственным способом сгенерировать признак отложенного прерывания являются команды спекулятивной загрузки. Другие команды его могут только "распространять".

В точке программы, где надо использовать результат спекулятивного выполнения, следует применять спекулятивную команду chk.s, проверяющую признак отложенного прерывания. Если оно имелось, chk.s передаст управление по указанному в ней адресу, по которому программист должен расположить коды обработки ситуации. Поскольку стало ясно, что спекулятивное выполнение команды действительно понадобилось, можно закодировать копию спекулятивно выполненного фрагмента программы, но уже с не спекулятивными командами загрузки.

Другой тип спекулятивного выполнения может иметь место, когда вслед за записью в память идет команда загрузки регистра, и невозможно заранее определить, не будут ли перекрываться в памяти используемые этими командами данные. В IA-64 имеются спекулятивные команды загрузки (Ld.a, Ldf.a...), которые называются "усовершенствованными" (advanced) командами загрузки. Аналогично взаимозависимости между командами по управлению, "расшиваемой" применением спекулятивных команд с "постфиксом" .s, продвинутые команды загрузки вместе с соответствующей командой проверки chk.a (аналог chk.s) позволяют исключить задержки выполнения при наличии взаимозависимости по данным.

Команды перехода. Адрес перехода выравнивается всегда на границу связки, т.е. управление передается на ее слот 0. Имеется команда перехода относительно счетчика команд, в которой явно кодируется 21-разрядное смещение. Эти переходы осуществимы в пределах +/-16 Мбайт относительно счетчика. В непрямых командах перехода адрес перехода задается в регистре BR.

Обычный условный переход br.cond, или просто br, использует значение кодируемого в команде предикатного регистра PR для определения истинности условия. Указав в команде PR0, в котором всегда лежит 1, можно получить безусловный переход. PR0 кодируется также в командах вызова процедур/возврата (br.call/br.ret). Имеется 5 типов команд перехода, применяемых для организации циклов. Команда br.cloop используется для организации циклов со счетчиком, в которых адрес перехода кодируется относительно IP. В команде используется регистр LC: если он не равен 0, его содержимое уменьшается на 1, и выполняется переход; если LC = 0, перехода не будет. Применение команд работы с циклами мы рассмотрим позже при обсуждении программно конвейеризованных циклов.

В расширении кода операции команды перехода можно закодировать подсказку для процессора о стратегии динамического или статического предсказания этого перехода.

Операции с плавающей запятой

Программная модель вычислений с плавающей запятой в IA-64, в отличие от IA-32, ориентирована на работу с регистрами FR, а не со стеком, что уже само по себе облегчает создание более высокопроизводительных программ. В IA-64 непосредственно поддерживается 6 типов данных, в том числе три стандарта IEEE754 (одинарная точность SP, двойная точность DP и двойная расширенная точность DE), 82-разрядный формат FR и 64-разрядные целые - со знаком и без знака. Формат DE, также как и формат с размещением двух чисел (SP) с плавающей запятой, используемый в векторных мультимедийных командах, унаследован архитектурой IA-64 от IA-32. Формат регистров FR включает 64-разрядную мантиссу, 17-разрядный порядок и 1 бит под знак числа. Кроме того, на уровне подпрограмм предлагается поддержка четверной точности.

В 64-разрядном регистре FPSR указываются признаки деления на ноль, переполнения порядка, исчезновения порядка, потери значимости, формат данных и другая информация о состоянии.

FP-команды загрузки имеют модификации, соответствующие всем аппаратно поддерживаемым типам данных, которые в ассемблере задаются последним символом мнемокода (Lfds - для SP, Ldfd - для DP и т.д.). Арифметические команды включают операции типа "умножить-и-сложить" и "умножить-и-вычесть", команды вычисления максимума/минимума, а также команды расчета обратной величины и обратного квадратного корня. Применение двух последних вместо команд деления и квадратного корня соответственно упрощает работу с конвейерами. Реализация команды обращения вместо деления была применена, как известно, еще в легендарном Cray-1.

Контрольные вопросы

  1.  Какие причины обусловили появление архитектуры IA-64?
  2.  Какое количество регистров предусмотрено в архитектуре IA-64?
  3.  Какова роль предикатных регистров?
  4.  Как используются регистры архитектуры IA-64 при вызове подпрограмм?
  5.  В чем суть спекулятивного (по предположению) выполнения команд?


РНК (ВА)

Преобразователь ВА→ФА     TLB команд

ВА

КЭШ команд  L1K

ФА

Неудача - обращение в кэш-память 2-го уровня (кэш L2)

Дешифратор команд

(1-2)τ

Общий буфер заявок (команд) к подсистеме обработки

ланировщик команд

1

2

3

4

команды

Временем записи в буфер заявок и временем чтения пренебрегаем




1. Исследование кожновегетативных рефлексов
2.  Расчет периодичности ТО и нормы межремонтного пробега с корректированием их нормативов
3. Зависимость черт характера от групп крови
4. Тема 11- ЭКОЛОГИЧЕСКОЕ ПРАВО Вопрос 1
5. 12 в Підготовка повстання молоді роки Хасану ібн Саббаха навчання ldquo;Дават ~ і джадидrdquo; Повст
6. Если на рынке действуют два производителя то такой тип рынка называется дуополией которая является част
7. правильные люди мотивированные обученные обладающие необходимыми для данной работы и данной организац.html
8. Психологическая лояльность бренду
9. Волновые свойства света Разработка интегрированного урока физика информатика 11 класс
10. Курсовая работа- Сущность управленческого учета, его структура и место в информационной системе предприятия