Введение в архитектуру компьютеров

Семантический разрыв между архитектурными решениями ЭВМ и его программным окружением


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

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

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

· оптимальны ли на все времена архитектурные решения, предложенные в 50–60?х годах?

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

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

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

Все это порождает ряд проблем: высокая стоимость разработки ПО, его ненадежность, большой объем программ, сложность компиляторов и ОС, наличие отступлений от правил построения ЯП.

Для уяснения семантического разрыва можно проанализировать взаимосвязи между каким?нибудь ЯП (например, ПАСКАЛЬ, С++, DELPHI, PL/1) и архитектурой ЭВМ, скажем с архитектурными решениями наиболее распространенных у нас компьютеров фирмы IВМ, и оценить "расстояние" между принципами, положенными в основу ЯП, и соответствующими принципами, положенными в основу архитектуры ЭВМ.


Попробуем сравнить несколько основополагающих принципов языка PL/1, широко используемых в ВС, с идеологией mainframe и определить адекватность их принципам, заложенным в IВМ 370.

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

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



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

Строки. В PL/1 используются строковые данные (или просто строка). Допустимые операции: слияние, выделение заданной части (подстроки), поиск строки по заданной подстроке, определение длины текущей строки, проверка присутствия одной строки в другой строке. Подобные возможности в системе команд IВМ 370 не предусмотрены. Более того, задача манипулирования строками битов (возможность, предоставляемая PL/1) осложняется еще и тем, что в IВМ 370 допускается адресация к группам из 8 бит, т. е. к байтам. И опять-таки все это надо реализовывать через компилятор, что существенно усложняет его работу.

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


Что есть в архитектуре IВМ 370? Только команда BALR (переход с возвратом). Но вклад этой команды в реализацию операций вызова процедуры настолько мал, что ее отсутствие осталось бы незамеченным. Компилятор мог бы заменить ее двумя командами: LA (загрузка адреса) и BR (переход безусловный).

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

Важно также сравнить имеющийся семантический разрыв с частотой использования соответствующих операций, предоставляемых ЯП. Из литературы известно, что 45 % всех арифметических операторов имеют дело с массивом или элементом массива, 16 % всех выполняемых операторов языка высокого уровня – это обращение к подпрограммам?процедурам, подпрограммам?функциям и операторы возврата. Компилятор с ФОРТРАНА, например, тратит до 15 % своего времени на установление связей между подпрограммами. Другие исследования говорят, что 19 % всех операторов программы составляют операторы CALL, RETURN, PROCEDURE.

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

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

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


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

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

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

Так, компилятор языка PL/1 фирмы IВМ генерирует 17 машинных команд для реализации оператора

C(I,J) = A(I,J) + B(I,J),

где А, В и С – массивы двоичных элементов одинакового размера в форме с фиксированной точкой.

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

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


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

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

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

Семантический разрыв порождает и некорректное использование языка программирования. Так, если в PL/1 мы объявляем переменную B как DCL B DECIMAL FIXED (2), т. е. двухразрядной десятичной с фиксированной точкой, а при использовании оператора присваивания напишем В = 200, то естественно ждать сообщение об ошибке. Но его нет. И при выводе на печать значения B мы получим 200. Все дело в том, что система IBM 370 может представлять десятичные числа, имеющие только нечетное количество цифр. Чтобы при полном устранении семантического разрыва не прийти к генерированию неэффективных объектных кодов, компилятор преобразует двухразрядные десятичные переменные в трехразрядные операнды машины. Если бы мы изменили соответствующие правила языка PL/1, то язык стал бы машинно-зависимым, с ориентацией на IBM 370.

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


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

Подобные некорректности можно найти и в других ЯП. Например в языке ФОРТРАН условный оператор IF имеет три точки перехода: = 0, > 0, < 0. Но это не широкие возможности языка, а зависимость его от архитектуры IBM 704, где встроенная операция сравнения в зависимости от результата своего выполнения передает управление одной из трех последующих команд.

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

Как следствие семантического разрыва – низкая производительность при проектировании программ. Создатель прикладного ПО тратит больше времени на управление памятью и пересылку данных, чем на собственную их обработку. Последние исследования показывают, что каждый 20?й оператор в PL/1?программах – это ввод и вывод информации.

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


Содержание раздела