Введение в двоичные технологии

в 10:48, , рубрики: АЛУ, информационный процесс, Исследования и прогнозы в IT, разрядность процессоров, метки: , ,
Комментарии к записи Введение в двоичные технологии отключены

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

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

1. Разрядность

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

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

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

2. Страница памяти

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

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

R — разрядность (ширина единицы памяти в битах)

A — количество адресуемых единиц памяти (объём адресного пространства)

C — количество машинных инструкций (объём командного пространства)

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

A = C = 2 ^ R

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

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

R = 2 ^ N

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

Очевидно, что N=4 — это минимальное приемлемое значение, поскольку 256 байт памяти при N=3 годится разве что для программирования ёлочных гирлянд. При N=5 получаем объём памяти, соответствующий последним достижениям в сфере ИТ. Но если считать главным назначением памяти, адресуемой процессором, хранение машинного кода (движка), а большую часть данных, которыми манипулирует этот движок, вынести за пределы адресуемого пространства (и как следствие — предполагать их носителями внешние устройства), то при таком объёме памяти (16 Гб) машинный код будет составлять лишь незначительную её часть, а всё остальное пространство будут занимать данные. В мегабите же машинного кода при N=4, написанного на эффективном асемблере, при условии вынесения данных за пределы адресного пространства можно будет разместить, пожалуй, ядро полноценной операционной системы. Так что в принципе моношестнадцатиразрядная архитектура способна обеспечить необходимый минимум ресурсов, а именно: 65536 слов адресуемой памяти и столько же машинных команд, составляющих полный список элементарных действий, выполняемых процессором.

Ограничение довольно существенное и создаёт ряд неудобств, вызванных прежде всего небольшим объёмом адресуемой памяти, требующим вынесения обрабатываемых данных за пределы адресного пространства. Удобно ведь, когда они «лежат под рукой» — то есть доступны процессору непосредственно, а не расположены «где-то там», во внешней памяти, откуда их необходимо пересылать во внутреннюю, что-то с ними делать, после чего отсылать обратно. Это момент является, пожалуй, самым узким местом моношестнадцатиразрядной архитектуры и чреват усложнением языка высокого уровня, поскольку написанные на нём программы не смогут абстрагироваться от нюансов, связанных с организацией обмена данными с внешними устройствами. Правильная расстановка акцентов позволяет решить все эти проблемы, ну и вообще при написании программы программисту было бы не лишним представлять себе динамику информационного процесса в полном объёме, а не на уровне отвлечённых абстракций. Также можно отметить, что идеология программирования в таком случае сместит акценты в сторону создания целостных и завершённых решений, помещающихся в одну страницу памяти размером в мегабит — а это немалый объём для обеспечения достаточно сложной функциональности. Принципиальные способы разрешения проблем, возникающих при урезании объёма адресуемой памяти до 64-х килослов, будут рассмотрены позже, здесь же я бы хотел акцентировать внимание на преимуществах от принятия N=4 в качестве фундаментальной константы.

Прежде всего это касается командного пространства (КП): 16-ти бит вполне хватает, чтобы реализовать АЛУ в его классическом виде. Так, увеличение разрядности современных процессоров до 32, а впоследствии — до 64, практически не сказалось на их системе машинных команд и по сути асемблер остался 16-разрядным. В принципе, ничего не мешает придумать машинный язык, система команд которого будет эффективно использовать 32 и более бит, но как показывает практика, острой необходимости в этом не возникает, поэтому здесь целесообразно принять 16-разрядный объём КП в качестве значения по умолчанию. К тому же N=4 обеспечивает дополнительное удобство, а именно:

R % N = 0

Соблюдение данного условия означает, что в одной ячейке памяти можно разместить целое число значений в диапазоне [ 0… R ) (например, для N=5 это условие не соблюдается, поскольку в данном случае R, равное 32-м битам, не делится на 5 без остатка). Поскольку разрядность является фундаментальным параметром, такое свойство позволит обеспечить в дальнейшем дополнительные преимущества, хотя в сравнении с предыдущими аргументами этот — третьего порядка значимости.

3. Внешнее ОЗУ

Итак, принятие числа 16 в качестве фундаментальной константы определяет базовую совместимость пространственного и временного аспектов информационного процесса, а именно: страницу памяти объёмом 64 килослова и перечень атомарных действий того же объёма и формата. Отсюда понятие разрядности, обеспечивающей этот общий объём и формат — мегабит «каши» из нулей и единиц, первично структурированный квантами по 16 бит, составляющих слово данных. Как следствие — одна ячейка памяти способна вместить адрес любой другой ячейки или содержит исчерпывающую информацию о выполняемом на данный момент действии. Предполагается, что независимо от деталей реализации системной архитектуры, разрядность обеспечивает совместимость её функциональных составляющих на первом уровне абстрагирования от физ.процессов, способствуя тем самым удобству формализации этой архитектуры. При этом упущение потенциальных возможностей от принятия такого ограничения предполагается несущественным — то есть далее я исхожу из предположения о том, что если рационально распорядиться этими начальными ресурсами, то можно будет создать на их базе эффективную информационную модель, скажем, любой сложности в пределах «почтальёна». Мегабит данных является ведь не верхним ограничителем объёма информационных ресурсов, а очередной (конкретно — третьей после бита и слова) ступенью формализации. Усложнение моделируемых процессов естественным образом ведёт к иерархической структуре управления, и полагая разрядность актуальной и для следующих ступеней их организации, получаем величину объёма внешнего ОЗУ, удобную своей совместимостью с шестнадцатиразрядной архитектурой: 65536 * 65536 страниц памяти = 8 ГБ. Перевожу на общепринятые байты, и как можно убедиться эта цифра находится в хорошем соответствии с текущими требованиями к ресурсоёмкости технологий. Принципиальное отличие состоит в том, что общая память не может быть адресована процессором напрямую или же придётся использовать для этого два слова памяти. Последнее само по себе не проблема, однако в связи с тем что составляющие систему устройства и процессоры должны между собой эту память как-то поделить, возникает множество нюансов по её распределению и обеспечению к ней доступа. Полагая изначально произвольным способ, которым это можно сделать, попытаюсь всё же выделить ключевые моменты, которые с необходимостью должна учитывать формализованная модель информационного процесса, построенная на философии моноразрядности.

4. Интегрированная система

До этого момента адресуемая память предполагалась ориентированной на хранение машинного кода, хотя это и не исключало возможности хранение в ней данных. Но так не получится обработать напрямую страницу памяти целиком, ведь хоть какую-то её часть должна занимать сама программа обработки. Поскольку предполагается принятие страницы в качестве стандартной единицы фрагментации данных, возникает необходимость эту проблему как-то решить. Проще всего это сделать путём включения в зону видимости процессора дополнительной страницы, которая могла бы послужить буфером, осуществляющим обмен данных с внешней памятью, не затрагивая страницу машинного кода (при этом два бита статуса придётся отвести под определение источника и приёмника соответственно, чтобы данные можно было гонять как в пределах одной из двух страниц памяти, так и между ними). Ввиду небольшого объёма страницы технологически не составит труда обеспечить пересылку данных одним кадром, не дробя этот мегабит на кванты по одному слову — что позволит свести на «нет» временные издержки на фрагментацию больших объёмов внешних данных, предназначенных для обработки процессором. Можно также обойтись без того чтобы гонять данные туда-сюда, используя технологию подстановки, позволяющую выбрать любую из 65536 страниц внешнего ОЗУ и адресовать её процессором напрямую. Если то же самое сделать со страницей кода, то можно будет выполнять хранящиеся во внешней памяти программы, снимая таким образом ограничение на их размер в 64 килослова и расширяя его до 4-х гигаслов.

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

— n ^ 2 | 2 ^ n

— | 2 ^ 0 = 1

2 * 2 = 4 | 2 ^ 1 = 2

4 * 4 = 16 | 2 ^ 2 = 4

16 * 16 = 256 | 2 ^ 4 = 16

256 * 256 = 65536 | 2 ^ 16 = 65536

— Как видно, что число 16 — величина не только минимально допустимая, но ещё и «самая круглая» среди близлежащих — то есть не вдаваясь в детали реализации информационной модели можно констатировать удобство расфасовки информации порциями именно такой ёмкости (вышеупомянутое условие «R % N = 0», соблюдающееся для следующей по списку величины разрядности, равной аж 256). Из приведённых ранее соображений можно также убедиться в том, что первичная развёртка принципа моношестнадцатиразрядности на иерархию управления хорошо согласуется с практической применимостью, ведь информационные процессы в зависимости от степени автономности рассматриваемого элемента системы дифференцируются согласно критерию быстродействия, обратно пропорционального информационной ёмкости процесса — из чего следует понятие «кэша», расписанного по уровням организации системы: «кэш первого уровня», «кэш второго уровня», и вся эта иерархия обычно укладывается в несколько этажей. При R=16 имеем следующие показатели:

кэш 0-го уровня (слово шириной в 16 бит): R-егистры процессора, предназначенные для адресации внутренней памяти (быстрее всего они будут обмениваться данными между собой в виду отсутствия необходимости выходить за рамки физической локализации АЛУ)
кэш 1-го уровня (блок памяти объёмом в 64 килослова = 1 мегабит): страницы внутренней памяти, предназначенные для непосредственной адресации процессором (одна или две — в большем их числе при наличии возможности полного обновления страницы за несколько процессорных тактов необходимости не возникает). Закреплю за этим типом памяти аббревиатуру АЗУ — то бишь адресуемая.
кэш 2-го уровня (внешнее ОЗУ ёмкостью в 64 килостраницы = 64 гигабит): память, используемая совместно устройствами, составляющими интегрированную систему — автономную единицу, завершённую модель информационного процесса, способную взаимодействовать с другими системами на общих основаниях (с точки зрения системы сетевая карта, обеспечивающая возможность межсистемного взаимодействия — лишь одно из устройств, функционирование которого может быть описано теми же выразительными средствами, что предназначены и для отражения процессов обмена данными внутри автономно функционирующей системы).
кэш 3-го уровня (ПЗУ ёмкостью до 64 килоОЗУ = 4 петабита): на жёсткий диск такого размера поместятся, например, все снятые в мире фильмы, так что информационную ёмкость этого уровня можно считать неограниченной. Также можно считать неактуальным очередное умножение на 65536, задающее следующий константный показатель информационной ёмкости. Собственно, и от этого нет особого толку, поскольку оперирование столь большими объёмами данных размывает представление о том, для чего они могут быть предназначены и как они могут быть структурированы. Кроме того, эта память слишком медленна, чтобы можно было считать её «кэшем» — так что в отличии от предыдущих уровней её нет смысла жёстко лимитировать. 4 гигаслова ОЗУ предполагаются достаточными для того, чтобы не возникало потребности слишком часто гонять данные в ПЗУ и обратно. Если же вычисления окажутся более ресурсоёмкими, то естественно было бы решить эту проблему путём задействования достаточного числа процессоров и эффективного распределения между ними функциональной нагрузки.

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

0 => 1: система машинных команд, исчерпывающе определяющая первичный способ квантования действий
1 => 2: язык программирования высокого уровня (предполагается естественной его объектно-ориентированная направленность, и как следствие — специализированность внешнего ОЗУ на хранении объектов)
2 => 3: язык системных запросов (макросов) — например командная или адресная строка, позволяющая выполнять сложные последовательности действий одной командой с множеством предусмотренных для неё параметров. По сути этот уровень можно считать сферой формализации ключевых функций операционной системы.
3 => 0: изначально предполагается условным в виду условной неисчерпаемости ресурсов, входящих в его состав. Исходя из представления о том, что одним точечным действием «по клику мыши» можно задействовать информационный процесс любой информационной ёмкости и сложности, считаем что сюда можно отнести любые поименованные действия, не вошедшие в три предыдущих категории языковых абстракций. Наделить этот уровень конкретикой позволяет его замыкание на уровень «железа» — о чём дальнейшие соображения.

По смыслу формальный язык следующего уровня (если считать его не нулевым, а четвёртым) предполагает выход за рамки автономной системы, и как следствие должен быть предназначен для именования действий, организующих межсистемное взаимодействие. Но как уже было сказано, межсистемный обмен данными образует собственную иерархическую структуру — начиная с низкоуровневых протоколов оцифровки аналоговых сигналов, через простой и универсальный протокол TCP-IP, на котором держится работа всемирной паутины, ну и так далее — по мере расширения горизонтов применимости универсализация программных реализаций становится всё более затруднительной. Здесь просто следует отметить, что формализация сетевых сообщений имеет свою специфику и как следствие собственную терминологическую структуру — начиная с простых алгоритмов по оцифровке непрерывных сигналов с последующим поэтапным приведением этой «каши из битов» к виду, «съедобному» для «потребляющих» её программ, которые сами выстраиваются в иерархию по мере усложнения принципов организации обмена данными от низкого уровня к высокому. То есть вся эта информация — она должна идти параллельно с развитием языков формализации, при этом не оказывая на них существенного влияния и являясь по сути лишь одной из неопределённого множества категорий задач, посредством этих языков решаемых. А поскольку все эти вопросы должны решаться на уровне операционной системы, то и способы их формального отображения следует как-то распределить на первых трёх уровнях системной организации. Например, сам TCP-IP пишется на asm-e, программа преобразования посылок данных в объекты — на C++, поддержка адресной строки оформляется в виде макроса ОС, ну а макрос — понятие достаточно растяжимое в плане функциональности и ёмкости действий, оперирующих объектами, уже сконструированными в ОЗУ объектно-ориентированными средствами. Он может содержать вложенные макросы, выполняющие каждый по отдельности достаточно сложные действия — так что при дальнейшем углублении вложенности не возникает повода для введения принципиально новой информации.

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

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

5. Арифметический и геометрический аспекты информационного процесса

Здесь я подведу промежуточные итоги.

Итак, разрядность R=16, зафиксированная в качестве фундаментального параметра информационной системы, совмещает пространственный (АЗУ) и временной (КП) аспекты информационного процесса, обеспечивая тем самым базовую совместимость функциональных устройств, и как следствие — упрощая построение формализованной модели различных процессов. Располагая такими начальными ресурсами, рекурсивным методом последовательно определяются три уровня системной организации (выделены в списках жирным), предполагающие отображение на иерархию языковых абстракций соответствующей выразительной мощности. С целью адаптации инженерной терминологии { двоичный разряд => ячейка => АЗУ => ОЗУ => ПЗУ } к лингвистической предлагаю для ассоциирования следующую последовательность: { буква => слово => страница => том => библиотека }

Последний уровень абстракции, замыкающий иерархию управления на нулевой (то есть опять же на физ.процессы, только с обратной стороны), выносится за рамки списка, поскольку рассмотрение его элементов имеет смысл лишь при наличии готовой архитектуры, на которой они могли бы выстраиваться — в то время как на уровне проектирования эту архитектуру лишь предстоит материализовать. С учётом приведённых выше соображений, этот способ состоит в определении схемы коммуникаций и выборе прошивок управляющих процессоров. Отсюда два принципиальных объекта формализации, первый из которых представлен информационными каналами для обмена данными и завязанными в них коммуникационными узлами, а второй — машинным кодом, квантованным элементарными действиями по преобразованию данных. Первый аспект можно назвать «геометрическим», поскольку его формальное отображение удобно представлять графически — в виде схем со стрелочками, указывающими направление циркулирования информационных потоков в системе, а также прямоугольничками и прочими условными обозначениями её функциональных составляющих. Второй, соответственно — «арифметическим», поскольку система команд процессора ориентирована на реализацию базовых математических вычислений. Также можно выделить критерий, на основании которого определяется принципиальная разница в их функциональном предназначении: если «геометрические» абстракции определяют способы организации пересылки данных между устройствами, то «математические» — способы их преобразования. При этом оба аспекта должны быть отображены в системе команд, то есть C = G U A, где C — командное пространство общим объёмом 65536 машинных инструкций, G — множество инструкций, инициирующих внешние механизмы обмена данными, A — команды внутренней адресации через регистры. Поскольку инструкции, составляющие множество G, абстрагируются от преобразования данных и по сути сводятся к команде MOV source --> destination, их формальное определение сводится к идентификации источника и приёмника. Но если для множества A все способы их идентификации заведомо в него включены, то команды из множества G, задействующие процессы по «обмену веществ с окружающей средой», не могут заведомо «знать», откуда и куда им придётся перекидывать данные, поскольку схема коммуникаций не отображена в составе АЛУ. Чтобы такая возможность было доступной, эту схему придётся полагать фиксированной на уровне проектирования системы — что лишит процесс проектирования гибкости, а дальнейшее рассмотрение этого вопроса смысла. Если же функциональность команд из группы G полагать заведомо неопределимой, и с учётом того что суть их действия всегда сводится к перегонке данных от некого источника к некому приёмнику, то нагрузкой на командное пространство для множества G можно пренебречь и свести его к одному элементу — единственной команде без параметров (назову её банально CMD). При этом информацию о том, что именно и куда именно следует пересылать, можно будет черпать из регистров, ссылающихся на произвольные участки АЗУ и ОЗУ — так что здесь нет принципиальных ограничений на объём и способ структурирования целевых данных, которыми манипулирует CMD. В предложенном случае информация об этом способе перекладывается на аппаратную реализацию той части процессора, которая отвечает за внешние коммуникации и как следствие — является составной частью их схемы. Теперь КП почти целиком принадлежит множеству A, а задачи формального определения системы машинных инструкций и принципов организации управления данными ничего теперь не мешает решать независимо друг от друга.

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

6. АЛУ

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

1. PC (Program Counter — программный счётчик) — отражает принцип пошагового выполнения программы в направлении увеличения адреса исполняемой команды. Вот стандартная последовательность действий с программным счётчиком: отправляем АЛУ на «съедение» команду, код которой содержится в ячейке АЗУ, на которую указывает PC; после чего инкрементируем PC (теперь он указывает на следующее после кода выполняемой в данный момент инструкции слово адресуемой памяти).

2. SP (Stack Pointer — указатель на вершину стека) — отражает принцип построения программы, предполагающий её оформление в виде иерархической структуры подпрограмм. Как следствие, должен запоминаться адрес возврата в то место, откуда подпрограмма была вызвана, а поскольку эти вызовы могут быть вложенными, необходимо отвести какой-то участок памяти под хранение всех этих адресов. Отсюда — организация стека по принципу LIFO (акроним Last In, First Out, «последним пришёл — первым ушёл») и два принципиальных способа его использования: «заталкивание» текущего адреса в стек ( PC --> (-SP) ) и «выталкивание» его оттуда обратно в программный счётчик ( (SP+) --> PC ). Возможны и другие способы использования стека, но эти два действия являются необходимыми для обеспечения возможности структурирования программы классическими средствами. Примечание: здесь и в дальнейшем знаки преддекремента (-) и постинткремента (+) будут ставиться непосредственно перед или после того, к чему они применяются — дальше по тексту будут приводится различные типы адресации, среди которых встречаются случаи неоднозначного их интерпретирования при использовании мнемоники асемблера процессоров PDP-11, который при первом рассмотрении будет полезен в качестве базового прототипа.

3. STATUS — содержит флаги, необходимые для условных переходов. Условие — оно либо соблюдается, либо не соблюдается, и для того чтобы это определить, нужны флаги состояния. Обязательных флага, отражающих результаты простейших математических действий, всего три: ноль/не ноль, положительный/отрицательный, есть перенос/нет переноса (последний нужен чтобы не терялись биты, вылезающие за пределы ячейки памяти). Для совместимости с 16-разрядной архитектурой регистр статуса конечно же удобно расширить до 16-ти флагов, которым будет несложно в дальнейшем найти применение, однако на первом этапе формализации я выделяю элементы, соответственно, лишь первой степени необходимости. Сюда ещё нужно добавить упомянутые выше два флага, путём переключения которых можно адресовать помимо памяти кода дополнительное АЗУ — страницу данных. Остальные 11, распределение функций которых требует больше фантазии чем это допустимо на первом шаге формализации, выносятся пока за рамки рассмотрения.

4. R-егистры общего назначения — играют роль локальных переменных, обеспечивающих насущные потребности выполняемой в данный момент подпрограммы. Могут также передавать значения между подпрограммами, взаимодействовать со стеком, адресовать память, одним словом, в отличии от первых трёх — неспециализированы. Над их количеством долго задумываться не приходится: 16 штук оптимально не только по идеологическим соображениям, но и потому что имея некоторый опыт программирования на асме могу сказать, что 8 мало (как правило эти регистры в программе «нарасхват», поэтому при таком их количестве много кода уходит на временную пересылку их значений в стек и обратно), в то время как 32 регистра для локальных функций — это уже излишество (хранить значения переменных можно ведь и в АЗУ). Далее для краткости регистры общего назначения будут обозначаться РОН-ами, а специального — соответственно РСН-ами.

5. Interrupt — прерывания от внешних устройств. Поскольку определяемая система команд абстрагируется от внешних информационных потоков, о прерывании здесь достаточно знать, что оно может произойти в любой момент, необходима подпрограмма для его обработки (соответственно — указание адреса, с которого она начинается), а также возможность возврата в то место, на котором основная программа была прервана. Чтобы не плодить сущности сверх необходимости и не забивать память избыточными данными (например — таблицей, в которой хранятся адреса обработки для каждого из прерываний), принимаем нулевой адрес за начало обработки любого прерывания, а в стек, помимо адреса возврата и текущего значения регистра статуса, помещаем информацию о самом прерывании. Если этой информации недостаточно для определения необходимых действий по обработке прерывания, дополнительная информация может быть загружена в адресуемую память посредством использования команд(-ы) из множества G. Увеличение нагрузки на быстродействие в сравнении со способом, использующим таблицу адресов, несущественно — просто в обработчик прерываний, расположенный по нулевому адресу, придётся добавить некоторое количество проверок и условных переходов, организующих ветвление по номеру прерывания, помещённого в момент его возникновения на вершину стека. Сами проверки можно расположить в порядке приоритетности проверяемых номеров — так чтобы прерывания с наибольшей частотой отвлечения процессора и требующие обработки в первую очередь проверялись соответственно первыми. Эти незначительные издержки на быстродействие с избытком компенсируются свойством монолитности страницы АЗУ, содержащей исполняемый код — что хорошо сказывается на цельности программной реализации. К тому же, все внутренние информационные потоки будут сосредоточены в трёх специализированных регистрах и R регистрах общего назначения — чего необходимо и достаточно для обеспечения базовой функциональности низкоуровневых средств программирования. Так архитектуру процессора легче всего удержать в голове, а память может быть распределена каким угодно образом — лишь бы с нулевого адреса шёл исполняемый код, а не данные, ну и ещё программа должна корректно обрабатывать прерывания в случае если таковые предусмотрены. На момент запуска процессора все регистры обнуляются, PC инкрементируется после отправления на АЛУ очередной команды, а SP декрементируется перед засылкой очередного слова данных в стек — так что при исходных нулевых значениях между стеком и машинным кодом программы никаких накладок возникать не должно.

На этом первый шаг формализации можно считать завершённым, и следующим я попытаюсь дать представление о том, сколько «весит» мегабит КП. Если вам знакома архитектура процессоров PDP-11, дальнейшие расчёты будет проще визуализировать. В древние времена у программистов они были в ходу, а потом их вытеснила враждебная идеология Intel-овских движков, и моему стремлению раскопать эту тему с первоначал во многом способствовала ностальгия по тем временам, когда количество «дырок» в организации компьютерной архитектуры было ещё терпимым. С этих позиций Intel-овский асемблер можно считать образцово-показательным примером того, как делать не нужно, поскольку ключевые несоответствия с предлагаемым здесь подходом прослеживаются в при первом ознакомлении с его мнемоникой. Например, в двухоперандной команде должен указываться сначала источник, а потом приёмник — то есть в естественной последовательности, отражающей причинно-следственные связи между физическими процессами, происходящими в «железе». Также машинные инструкции процессора Intel не используют в явном виде PC — то есть налицо явные признаки CISC-ориентированной идеологии, стремящейся «скрыть за ширмой» аппаратную реализацию машинных инструкций. Короче говоря, RISC-и рулят, а СISC-и гоухом.

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

6. Система машинных инструкций

Итак, в нашем распоряжении 3 специальных и 16 общих регистров, к которым применимо некоторое множество способов адресации памяти. В исходном состоянии память принимается чистой и «незапятнанной» специализированной информацией, требующей введения каких-то иных сущностей помимо перечисленных на первом шаге итерации. Процессор стартует с нулевого адреса страницы кода, последовательно выполняет команды, совершает условные и безусловные переходы, вызывает подпрограммы, и наконец — отвлекается на прерывания (последние допустимо вообще никак не отображаться на множество А, поскольку алгоритм возврата из прерывания можно позаимствовать от обычного способа завершения подпрограммы командой RET, сводящийся к восстановлению PC и STATUS-а из стека, чтобы программа смогла корректно продолжить свою работу).

Чтобы проще было «взвесить» навскидку КП, обратим внимание на то обстоятельство, что большую часть его объёма составляют машинные инструкции с двумя операндами (трёхоперанндные можно заведомо исключить, так как они явно не вписываются в страницу КП, да и не очень-то согласуются с представлением о низком уровне). Три бита из 16-ти «откусываются» сразу на указание номера команды, чтобы вместить классическую семёрку { MOV, CMP, ADD, SUB, AND, OR, XOR }, потеря любой которых была бы чревата значительным упущением возможностей, в то время как в добавлении к этому списку новых команд уже нет насущной потребности, поскольку через них можно сделать всё остальное. Умножение и деление реализуются алгоритмически и в отличии от перечисленных команд аппаратный способ их реализации на мультиплексорах является элементарным. Данное требование целесообразно зачислить в список принятых по умолчанию решений (скажем — галочкой на опции «trivial instructions only» ): все команды, составляющие КП, должны быть не сложнее операций сложения/вычитания. На уровне проектирования информационных систем усложнять процессор нет смысла, поскольку с учётом возможности собрать его, в идеале, по атомам, все проблемы по распределению вычислительной нагрузки можно решить путём регулирования взаимного расположения процессоров в пространстве, где скорость света будет единственным ограничителем скорости их взаимодействия. Как следствие, достижение требуемого быстродействия будет предпочтительнее осуществить путём увеличения числа процессоров и организации их эффективного взаимодействия программными средствами, при том что каждый процессор по отдельности в силу простоты своего устройства способен будет обеспечить достаточно высокие показатели быстродействия. Так что идеология RISC предлагаемому подходу будет явно дружественной — тем более что места в командном пространстве и так впритык. И наконец, главное удобство от принятия соглашения о тривиальности составляющих АЛУ машинных инструкций состоит в выравнивании действий по сложности на фундаментальном уровне проектирования информационных систем — в таком случае термин «язык низкого уровня» искомому решению будет в полной мере соответствовать.

Дальнейшая оценка информационной ёмкости КП будет опираться на представление о том, что 7/8 его объёма занимают инструкции с двумя операндами, один из которых представлен в коде команды полем адресации источника, а второй — полем адресации приёмника. Поле адресации должно содержать исчерпывающую информацию о регистре, через который производится адресация, а также о самом способе адресации. Регистров всего 19, то есть на указание номера регистра требуется по усреднённой оценке log2(19) бит. Три бита ушло на указание номера команды, остальные 13 дают два поля адресации по 6.5 бит на каждое, так что навскидку имеем 2 ^ [ 6.5 — log2(19) ] ~ 4.8 видов адресации на операнд. АЛУ процессоров PDP-11 использует 3 бита на указание номера адресации и столько же на номер регистра — то есть включает 8 регистров и 8 способов адресации через них, при том что PC и SP входят в число РОН-ов. Последнее свойство полезно тем, что позволяет сделать систему команд ортогональной, и как следствие — даёт возможность отдельно запоминать команды, и отдельно — методы доступа к операндам (чем собственно и привлекали в своё время эти процессоры программистов). В данном же случае такой подход неприемлем по двум взаимодополняющим причинам:

1. Для специализированных регистров (главным образом для PC) многие способы адресации неприменимы, поскольку ведут либо к гарантированному зависанию ( (-PC) ), либо к сбою программы вследствие выполнения данных вместо кода ( (PC) ). Как следствие, КП содержит инструкции, коих немалое число, формально допустимые, но на практике неприменимые. Прямой адресации РСН-ов вообще следует избегать — с точки зрения адресации в этом состоит их принципиальное отличие от РОН-ов, для которых прямая адресация считается естественной, в то время как использование РСН-ов с целью временного хранения значений по понятным причинам неприемлемо. То есть для PC и SP началом отсчёта является косвенная адресация, а не прямая, ведь прежде всего нас интересует не само значение этих регистров, а содержимое ячейки, на которую оно ссылается. Сказанное не означает полного исключения из АЛУ возможности прямой адресации РСН-ов, и если программисту потребуется, скажем, восстановить стек напрямую или перепрыгнуть дальше, чем это позволяют локальные переходы, то для подобных целей должны быть предусмотрены соответствующие инструкции. Разница состоит в том, что эти инструкции будут проходить в системе команд не на общих основаниях, а в виде небольшого числа специализированных («поштучных») команд, дабы не нагружать КП и исключить практически малоприменимые способы адресации. Возьмём, к примеру, применение к PC и SP побитовых операций AND, OR и XOR — гипотетически такая возможность допустима, но потребуется немало фантазии, чтобы придумать ситуацию, когда такая необходимость возникнет (а если и возникнет, то из этого будет следовать лишь то, что придётся сделать то же самое двумя командами вместо одной). Таким образом, использование в программе РСН-ов имеет свою специфику, в соответствии с которой должно определяться множество допустимых действий над каждым из них. Есть и другие принципиальные отличия от набора команд PDP-11, из-за которых дальнейшее его сопоставление с определяемой здесь реализацией АЛУ будет менее показательным.

2. Вторая причина, как уже было сказано, состоит в том, что в КП слишком мало места, чтобы можно было позволить себе так им разбрасываться, как это было описано в предыдущем пункте — в связи с чем ортогональный набор команд придётся отменить. Увеличение числа РОН-ов с 6-ти (PDP-11) до 16-ти привело к урезанию числа способов адресации с 8 до 4.8 в среднем на операнд, вследствие чего адресация стала «узким местом» 16-разрядного АЛУ, использующего в общей сложности 19 регистров. Например, для РОН-ов в командное пространство помещается лишь 4 стандартных типа адресации: R, ®, (R+), (-R). В принципе, в большем их числе особой потребности и не возникает, поскольку двойная косвенная адресация (взятие адреса по адресу) по вышеупомянутым причинам актуальна лишь для PC и SP. А про остальные, включённые в состав 8-ми PDP-шных адресаций, можно сказать, что они бы не помешали, но если их исключить, то это не будет большой потерей ввиду нетипичности фигурирования РОН-ов в других типах адресации. Вообще говоря, для PC применимы лишь два способа адресации: (PC+) и &(PC+) (первый называется «косвенная автоинкрементная», второй — «двойная косвенная автоинкрементная»). Постинкремент необходим для того, чтобы перепрыгнуть через слово данных после его взятия АЛУ на обработку — во избежание выполнения случайной команды, предназначенной для выполнения следующей. Как следствие, первый способ адресации по смыслу означает взятие константы — значения, которое находится в момент исполнения команды в ячейке, расположенное в АЗУ следом за кодом этой команды (назовём эту ячейку «текущей»), а второй — обращение к переменной (на этот раз в текущей ячейке содержится адрес той ячейки, где хранится значение переменной — отсюда двойная косвенность). Использование первого вида адресации имеет смысл лишь применительно к источнику, поскольку данные обычно пересылаются из константы, а не наоборот — в константу. В принципе, ничего не мешает записать какие-то данные по текущему адресу, но смысл это имеет лишь в том случае, если предполагается дальнейшее их использование — для чего необходимо знать адрес текущей ячейки. Получается что константа в данном случае превращается в переменную, которую можно было бы хранить и в любой другой ячейке — то есть на приёмнике данный способ адресации будет избыточным, и при скурпулёзном отборе адресаций согласно критерию полезности его следует исключить. Таким образом, если PC помимо этих двух способов (формально их даже не два, а полтора) нет смысла адресовать как-то по-другому, то для РОН-ов большее количество адресаций просто не помещается в адресное пространство, и если оставаться в рамках классической реализации АЛУ, то можно считать эти способы необходимыми и достаточными.

Зато на SP и STATUS в командном пространстве остаётся достаточно места, чтобы обеспечить более широкие возможности их адресации. Стек обычно используется в программе достаточно часто, чтобы уделить ему внимание и сопоставить более солидное множество адресаций. В текущей реализации это множество содержит 16 видов адресации, половину из которого составляют адресации со смещением { N(SP), N+(SP), -N(SP), &N(SP), &N+(SP), &-N(SP), &N(SP)+, &N-(SP) }, где N — байт смещения, под который отведена половина регистра статуса — то есть величина смещения от вершины стека не может превышать 255. Зато в отличии от системы команд PDP-11 здесь N является переменной, а не константой — что позволяет применять к нему автоинкремент/автодекремент и доставать значения из разных мест стека, оставляя нетронутой его вершину. Как правило нас интересуют данные, расположенные не выше вершины стека (собственно, занесённые в стек, а не вышележащие, которые обычно считаются уже отработанными), следовательно включать в диапазон величины смещения отрицательные значения нецелесообразно. Остальная половина адресаций выглядит следующим образом: { (SP), (+SP-), (-SP+), &(SP), &(SP+), &(SP-), &(SP)+, &-(SP) }. Во избежание путаницы в интерпретации второго и третьего элементов в списке отмечу, что это одно из немногих исключений асимметрии адресаций для источника и приёмника (здесь для источника предполагается пост-инкремент/декремент, в то время как для приёмника — пред-. Последние две адресации, как и в предыдущей восьмёрке, предполагают использование целевой ячейки стека в качестве счётчика, инициализированного начальным адресом массива памяти. Элементы списка подбирались по принципу наименьшей надуманности и наибольшей полезности, и на данный момент мне эта подборка, количество элементов которой подогнано под «круглое» число 16, видится мне оптимальной.

Регистр статуса оказался наиболее продуктивным в плане разнообразия способов адресации. Задаваясь вопросом о том, как наиболее эффективно распорядиться остальными 11-ю битами, я пришёл к выводу, что лучше всего разбить STATUS на два байта, один из которых будет содержать флаги специального назначения, а второй — общего (по аналогии с базовой классификацией регистров). Каждый из байтов делится в свою очередь на два полубайта. Первый специализированный полубайт содержит 4 арифметических флага, 3 из которых описаны выше, а второй полубайт — 4 «геометрических» флага, 2 из которых отведены под переключатели адресуемых страниц памяти. Арифметические флаги можно «добить» флагом чётности, проверяющим младший бит результата (для симметрии со знаковым флагом, проверяющим старший разряд), а предназначение двух оставшихся «геометрических» флагов зарезервированы под функции внешних коммуникаций, которые пока не определены. Флаги специального назначения (ФСН-ы) выношу за рамки дальнейшего рассмотрения — с точки зрения адресации здесь прежде всего интересны ФОН-ы, точнее — байт общего назначения, один из примеров использования которого приведён выше (там где про адресацию SP со смещением). Обозначив полубайты переменными Bx и By, представлю начальный список адресаций регистра статуса: { B, Bx, By } — то есть к байту в целом и к полубайтам по отдельности применим прямой способ адресации, можно хранить там значения и преобразовывать их на общих основаниях. Но главная цель дальнейшей фрагментации регистра статуса состояла в том, чтобы хранить в полубайтах номер регистра, и как следствие — обеспечить возможность индексации РОН-ов: { Rx, Ry, (Rx), (Ry) }. Пример: MOV (Rx),(-SP) — переслать в стек значение переменной, адрес которой помещён в регистр, номер которого указан в Bx. Теперь в РОН-ах можно хранить короткие массивы, ссылаться на них по значению, ну и вообще — образуется дополнительный этаж в иерархии доступа к памяти: 4-разрядный мини-регистр указывает на 2^4=16-разрядный РОН (слово), а тот в свою очередь может ссылаться на ячейку 2^16=65536-словного АЗУ (страница). Весьма полезный и перспективный наворот, расширяющий возможности структурирования процессов обработки данных, а также нетребовательный к месту в КП. Ещё одна возможность, которую я тоже думаю не стоит пренебрегать, состоит в привязке полубайтов общего назначения к арифметическим флагам (фигурирующими далее под индексами z, n, c, p): { Rz, (Rz), Rn, (Rn), Rc, (Rc), Rp, (Rp), Bz, Bn, Bc, Bp }. Пример: MOV (SP+),(Rn) — взять с вершины стека значение и переслать его в ячейку, адрес которой указан в регистре, номер которого в зависимости от состояния флага n находится либо в Bx, либо в By (остальные действия в списке можно определить по аналогии). Предложенный способ использования полубайтов статуса существенно повышает выразительную мощность составляющих командное пространство абстракций, при том что аппаратная реализация сопоставленных им действий не выходит за рамки тривиальности, полагаемой необходимым условием соответствия идеологии RISC. Здесь, к слову, пригодилось вышеупомянутое преимущество числа 16, как «самого круглого» (для которого соблюдается условие R % N = 0): номер 16-разрядного регистра можно разместить в другом 16-разрядном регистре (в данном случае — в регистре статуса) аккурат 4 раза.

На данном этапе определения АЛУ командное пространство поделено на 8 равных частей, из которых 7 закреплены за двухоперандными командами, а 8-я отведена под остальные. Следующей по ёмкости идёт группа инструкций, осуществляющих локальные переходы и включающих в свой код величину смещения относительно места их выполнения. Отводить под смещение меньше байта нет смысла, а больше не получится по всё той же банальной причине нехватки места. От оставшихся 13 бит «откусываем» байт смещения, и остаётся 5 бит для указания номера команды — то есть их не может быть больше 32-х. И ещё как минимум необходимо выделить место под однооперандные команды. Много там не «откусишь» (обойтись менее чем 24-мя командами из этой группы сложновато), но поскольку однооперандные команды «весят» в 2 раза меньше в силу того что им требуется 7, а не 8 бит на представление операнда, то из 8-ми команд ветвления можно сделать 16 однооперандных — чего в условиях жёсткой экономии командных ресурсов вполне хватает. Данные показатели близки к PDP-шным, ну и опыт выкладывания мозаики согласно заданным в условии этой задачки критериям показывает, что такие пропорции оптимальны и устойчивы, а именно: 7/8 командного пространства занимают двухоперандные команды, а оставшуюся 8-ю часть делят между собой однооперандные команды и локальные переходы в соотношении объёмов 1: 3. Полная система машинных инструкций АЛУ не исчерпывается этими тремя группами команд, но они являются наиболее ходовыми в программе, а с точки зрения нагрузки на командное пространство — определяющими. Для остальных же (безоперандных, флаговых и прочих, возможно не вписывающихся в общий формат команд) предполагается выделение места из остатков, нетронутых таблицами адресаций трёх базовых множеств машинных инструкций. Таким образом, на втором шаге итерации получаем 7 + 16 + 24 + { примерно столько же дополнительных } команд, составляющих полную реализацию АЛУ. Однозначный их состав определён лишь в первой группе в виде «классической семёрки»; состав второй группы предполагает включение в неё с десятка стандартных команд, встречающихся практически в любых реализациях АЛУ, и ещё нескольких полезных на уровне обеспечения базовых средств низкоуровневого программирования (скажем — перестановка байтов в слове); третья группа содержит команды ветвления и организации циклов в диапазоне байта смещения; остальные обеспечивают дополнительные удобства и гибкость написания машинного кода. При этом одна команда может содержать в себе от 1 (безоперандные) до 8192 (двухоперандные) машинных инструкций.

Ещё не помешало бы снабдить процессор дополнительными регистрами — такими как TMС (счётчик системного таймера), TMR (регистр предустановки системного таймера, задающий период отсчёта), PTI (порт ввода), PTO (порт вывода) и CFG (регистр системной конфигурации, содержащий предделители для таймера, регулирующие его скорость отсчёта; флаг разрешения прерывания от таймера для обеспечения возможности тактирования процессов; также могут оказаться полезными флаги, обеспечивающие синхронизацию работы таймера с состоянием портов ввода и вывода). В таком случае придётся добавить в множество G некоторое количество инструкций, осуществляющих обмен данными между основными и только что перечисленными дополнительными регистрами.

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

7. Итоги

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

1. Принимаем разрядность фундаментальной константой, призванной совместить пространственный и временной аспекты информационного процесса, через которую рекурсивно определяем трёхуровневую архитектуру, пространственный аспект которой задаёт ёмкость единицы памяти на каждом из уровней { слово (ячейка) => страница (АЗУ) => том (ОЗУ) }, а временной — сложность процессов, инициируемых распределёнными по этим уровням управляющими действиями { машинная инструкция (команда) => управляющая прошивка (программа) => интегрированная система (собственно, компьютер) }

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

Формально оба языка должны пересекаться в одном КП — то есть команды управления внешними коммуникациями должны быть включены в число обрабатываемых АЛУ. Но реально последние могут быть представлены в системе команд единственной инструкцией, результат выполнения которой зависит от содержимого регистров, в которые предварительно заносится информация об источнике и приёмнике, объёме пересылаемой информации, а также сопутствующие данные, определяющие характер информационного обмена. Много места эта информация не потребует: 2 регистра способны вместить номер любого из 4-х миллиардов компьютеров, ещё 2 — номер любого из 4-х миллиардов файлов на этом компьютере, следующие 2 — указать номер любой ячейки в файле размером до 4-х гигаслов. То есть, для однозначной идентификации источника и приёмника (скажем, в пределах всемирной паутины и с точностью до адреса конкретного слова данных, хранящегося в памяти конкретного компьютера) понадобится 6*2 = 12 регистров. Ещё 2 потребуется на то чтобы указать объём пересылаемой информации, после чего останется 2 на размещение уточняющих данных — так что в 16 регистров вполне можно уложиться. Если же информации для исчерпывающего описания выполняемых действий потребуется больше, то ничего не мешает использовать часть регистров в качестве указателей на блоки памяти, размещённые в АЗУ.

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

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

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

Автор: axby

Источник

Поделиться новостью