Помимо выполнения основных операций по отдельности, вычислительная машина должна уметь выполнять совокупность таких операций в соответствии с заданной последовательностью, точнее, логической схемой, что и является конечной целью вычислений. В традиционных аналоговых машинах, типичным примером которых служит дифференциальный анализатор, последовательность операций достигается следующим образом. В машине должно быть столько органов, сколько требуется для выполнения основных операций в рамках желаемых вычислений, т. е. достаточно дифференциалов и интеграторов (для двух основных операций (x + y) / 2 и ∫t x (t) dy (t) соответственно; ср. выше). Эти органы, т. е. их входные и выходные диски (точнее валы), следует соединить друг с другом (с помощью зубчатых колес в ранних моделях и электрических устройств слежения – сельсинов – в современных машинах) таким образом, чтобы получилась как бы копия требуемого вычисления. Отметим, что данная машина должна позволять использующему ее человеку инициализировать ее схемой вычислений, т. е. сообщить ей задачу. Если в первых машинах (с зубчатым колесом; ср. выше) инициализация осуществлялась при помощи механических средств, то в новейших машинах (с электрической связью; ср. выше) она реализуется с помощью коммутации. Тем не менее в обоих типах машин такая инициализация фиксируется на весь период решения задачи.
Коммутационное управление
В некоторых новейших аналоговых машинах введено еще одно усовершенствование – электрические коммутационные связи. Эти связи управляются электромеханическими реле; следовательно, их можно изменять посредством подачи управляющего напряжения на электромагниты, замыкающие и размыкающие эти реле. Управление электрическим напряжением осуществляется с помощью перфорированных бумажных лент, которые запускаются и останавливаются (перезапускаются и вновь останавливаются и т. д.) электрическими сигналами, зависящими от хода выполнения вычислений.
Логическое управление с помощью перфоленты
Последнее утверждение означает, что определенные вычислительные органы машины способны фиксировать некие заранее заданные условия (например, знак числа поменялся на отрицательный, одно число стало меньше другого и т. д.). Заметим: если числа представлены электрическим напряжением или током, то их знаки могут быть распознаны с помощью выпрямителей; если используется вращающийся диск, знак показывает, как именно диск прошел нулевое положение (вращаясь вправо или влево); одно число становится меньше другого, когда знак их разности становится отрицательным и т. д. Таким образом, логическое управление с помощью ленты, а точнее – управление на основе состояния вычислительного процесса в сочетании с лентой – накладывается на управление на основе фиксированных связей.
В цифровых машинах с самого начала применялись другие системы управления. Однако, прежде чем перейти к их обсуждению, я хотел бы сделать несколько общих замечаний касательно цифровых машин и их взаимосвязи с аналоговыми машинами.
Принцип только одного органа для каждой основной операции
Необходимо подчеркнуть, что в цифровых машинах обычно предусмотрен только один орган для каждой основной операции, в отличие от аналоговых машин, в которых должно быть достаточно органов для каждой основной операции в зависимости от требований решаемой задачи (ср. выше). Тем не менее следует отметить, что это, скорее, исторический факт, нежели объективная необходимость: аналоговые машины (с электрическими связями; ср. выше) тоже могут иметь всего один орган для каждой основной операции. Логическое управление таких машин будет рассмотрено ниже. (Читатель может с легкостью убедиться сам, что новейший тип управления аналоговых машин, описанный выше, представляет собой переход к данному режиму работы.)
Также следует отметить, что некоторые цифровые машины в той или иной степени отклоняются от принципа «одна основная операция – один орган», однако работу таких машин можно свести к традиционной схеме путем несложных реинтерпретаций. (В некоторых случаях достаточно объединить две машины с необходимыми устройствами двусторонней связи.) Впрочем, здесь я не буду углубляться в данный вопрос.
Потребность в специальном органе памяти
Принцип только одного органа для каждой основной операции требует, однако, большого количества органов, предназначенных для пассивного хранения чисел – результатов различных частичных, промежуточных вычислений. Иными словами, каждый такой орган должен быть способен сохранить число, полученное от другого органа (предварительно стерев число, которое было сохранено ранее), и воспроизвести его по запросу, а именно – передать его некоему третьему органу. Такой орган называется регистром памяти, совокупность подобных органов – памятью, а количество регистров в памяти – емкостью этой памяти.
Теперь перейдем к описанию основных способов управления, применяющихся в цифровых машинах. Наилучший способ это сделать – описать два основных типа и рассмотреть некоторые очевидные принципы их сочетания.
Управление с помощью управляющих точек
Первый широко распространенный метод управления можно описать (с некоторыми упрощениями и допущениями) следующим образом.
Машина содержит некоторое количество органов логического контроля, называемых управляющими точками. (Количество таких управляющих точек может быть весьма велико. В некоторых новейших машинах оно достигает нескольких сотен.)
При самом простом способе использования данной системы каждая управляющая точка связана с одним из органов основных операций, который она приводит в действие, а также с регистрами памяти, одни из которых поставляют числовые входные данные для этой операции, другие – принимают ее результат. После определенной задержки (достаточной для выполнения операции) или получения сигнала «выполнено» (при вариабельной длительности операции, если максимальная продолжительность не определена или слишком велика, требуется дополнительная связь с органом, выполняющим данную основную операцию) управляющая точка задействует следующую управляющую точку, своего «преемника». Эта точка действует аналогичным образом согласно собственным связям, и т. д. В отсутствие дальнейших действий данная система обеспечивает схему безусловного, бесповторного вычисления.
Более сложные схемы применяются в случаях, когда некоторые управляющие точки, так называемые точки разветвления, связаны с двумя преемниками и могут находиться в двух состояниях, скажем А и Б, причем А направляет процесс к первому преемнику, а Б – ко второму. Обычно управляющая точка находится в состоянии А. Тем не менее она связана с двумя регистрами памяти; определенные события в этих регистрах могут заставить ее перейти из состояния А в состояние Б или, наоборот, из состояния Б в состояние А. Так, например, появление отрицательного знака в первом регистре заставит ее перейти из состояния А в состояние Б, а появление отрицательного знака во втором – из Б в А. (Обратите внимание, что, помимо хранения цифрового обозначения числа [ср. выше], регистр памяти обычно хранит и его знак [+ или – ]; для этого достаточно двузначного маркера). В этом случае открываются самые разнообразные возможности. Два преемника могут представлять две совершенно разобщенные ветви вычисления, зависящие от заданного числового критерия (управляющего переходом из А в Б, тогда как переход из Б в А используется для восстановления первоначального условия для нового вычисления). Возможно две альтернативные ветви объединятся позже, в общем преемнике. Другая возможность возникает тогда, когда одна из двух ветвей, скажем, ветвь, которая управляется состоянием А, в действительности ведет назад, к первой из упомянутых управляющих точек (точек разветвления). В этом случае мы имеем дело с итеративной процедурой, повторяющейся до тех пор, пока не будет удовлетворен некий числовой критерий (тот, который вызывает переход из А в Б; ср. выше). Таков, разумеется, базовый итеративный процесс. Все эти приемы могут сочетаться, накладываться друг на друга и т. д.
Необходимо отметить, что в данном случае, как и в случае коммутационного управления в аналоговых машинах, упомянутого ранее, совокупность задействованных (электрических) связей осуществляет первичную инициализацию – описание задачи, которую необходимо решить, т. е. намерения человека, использующего машину. Следовательно, это одна из разновидностей коммутационного управления. Схема коммутации может меняться от одной задачи к другой, но (по крайней мере, в простейших устройствах) в рамках решения отдельно взятой задачи всегда остается неизменной.
Данный метод поддается усовершенствованию различными способами. Каждая управляющая точка может быть связана с несколькими органами, задействуя две и более операции. Коммутационное соединение может (как в примере с аналоговыми машинами, приведенном выше) фактически управляться электромеханическими реле; эти электромеханические реле могут регулироваться лентами, а ленты в свою очередь могут двигаться под контролем электрических сигналов, возникающих в ходе вычислений. Однако здесь я не буду рассматривать все возможные варианты.
Управление при помощи команд, хранимых в памяти
Второй основной метод управления, который постепенно вытесняет первый, можно описать (опять-таки с некоторыми упрощениями) следующим образом.
Формально эта схема имеет некоторое сходство со схемой коммутационного управления, упомянутой выше. Однако вместо управляющих точек здесь используются команды. В большинстве вариантов данной схемы команда физически представляет собой то же самое, что и любое число (того типа, которым оперирует машина; ср. выше). Таким образом, в десятичной машине это последовательность десятичных цифр (12 десятичных цифр, как в примере выше, со знаком или без него, и т. д. Иногда в стандартном числовом пространстве содержится несколько команд, но здесь мы не будем рассматривать этот случай).
Команда указывает, какая основная операция должна быть выполнена, из каких регистров памяти должны быть получены ее входные данные и в какой регистр памяти должен быть отправлен выход. Это предполагает, что все регистры памяти пронумерованы последовательно. Номер регистра памяти называется адресом. Целесообразно пронумеровать также и основные операции. В таком случае команда просто содержит номер операции и адреса регистров памяти в виде последовательности десятичных цифр (в фиксированном порядке).
Существует несколько вариантов этой схемы, однако для данного контекста они не особенно важны. Команда может, как описано выше, управлять более чем одной операцией; она может требовать изменения содержащихся в ней адресов определенным образом перед ее выполнением (обычное – и практически самое важное такое изменение заключается в том, что ко всем соответствующим адресам добавляется содержимое определенного регистра памяти). В других случаях эти функции могут управляться особыми командами или же команда может влиять лишь на некоторые из составляющих действий, перечисленных выше.
Важнейшим свойством каждой команды является следующее. Как и управляющая точка в предыдущем примере, каждая команда должна определять своего преемника (с разветвлением или без него; ср. выше). Как я уже отмечал ранее, любая команда «физически» есть то же самое, что и число. Поэтому в ходе решения задачи абсолютно естественно хранить ее в регистре памяти. Другими словами, каждая команда хранится в памяти в определенном регистре, т. е. по определенному адресу. Отсюда вытекает несколько возможных подходов к преемнику команды. Так, можно обозначить, что преемником команды с адресом Х – если не указано противоположное – является команда с адресом Х + 1. Противоположностью является команда перехода – особая команда, указывающая, что преемник находится по адресу Y. Возможен и другой вариант: каждая команда включает переход, т. е. явно указывает адрес своего преемника. Разветвление удобнее всего реализовать с помощью команды условного перехода. Данная команда указывает, что адресом преемника является Х или Y в зависимости от определенных числовых условий – например, отрицательное или положительное число с адресом Z. Такая команда, следовательно, должна содержать число, характеризующее данный конкретный тип команды (тем самым оно играет ту же роль и занимает то же место, что и номер основной операции, о котором мы говорили выше), а также адреса X, Y, Z в виде последовательности десятичных цифр (ср. выше).
Необходимо отметить важное различие между этим способом управления и коммутационным управлением, описанным ранее. При коммутационном управлении управляющие точки представляют собой реальные физические объекты. Их взаимное расположение относительно друг друга выражает решаемую задачу. В способе, рассмотренном выше, команды являются абстрактными объектами, записанными в память машины. Таким образом, задачу описывает содержание данного конкретного сегмента памяти. Соответственно этот способ управления можно назвать управлением, хранимым в памяти.
Принцип работы командного управления
Поскольку команды, осуществляющие все управление, хранятся в памяти, данный способ управления отличается бо́льшей гибкостью. В самом деле, машина под управлением команд может извлекать числа (или команды) из памяти, обрабатывать их (как числа!) и возвращать в память (в то же или другое место); т. е. изменять содержание памяти – фактически это ее нормальный режим работы. Следовательно, она может менять команды, которые определяют ее действия. Это позволяет использовать разнообразные сложные системы команд, которые последовательно изменяют себя и, соответственно, вычислительные процессы, которыми они управляют. Благодаря этому становятся возможны более сложные процессы, нежели простые итерации. Хотя такое может показаться нереальным и сложным, подобные методы широко используются и играют важнейшую роль в современной практике машинных вычислений (вернее, в планировании таких вычислений).
Разумеется, система команд – а именно задача, подлежащая решению, намерение пользователя – сообщается машине посредством ее загрузки в память. Обычно это делается с помощью заранее подготовленной ленты или другого аналогичного посредника.