Лайфхаки по программированию от Алана Тьюринга (Mark I/II)

В процессе обсуждения в комментариях соседней темы я набрёл на замечательное руководство от 1951 года по программированию серии одних из первых британских ЭВМ — Manchester/Ferranti Mark I/II за авторством самого Алана Тьюринга: curation.cs.manchester.ac.uk/computer50/www.computer50.org/kgill/mark1/RobertTau/turing.pdf
И там на странице 55 есть замечательная секция «Programming Hints» — «Приёмы и трюки программирования».
Конечно я не мог не ознакомится с тем чем и как дышала передовая программерская мысль в 1951 году.

Для начала скопирую сюда немного ликбеза о том что это за ЭВМ вообще такая была (крайне сжато и только по верхушках, более обстоятельная обзорно-историческая статья возможно последует позднее).
Классическая архитектура аккумулятор-память. ОЗУ вместе с регистрами хранилось в электронно-лучевых трубках Уильсона.
20-битная инструкция как бы состоит из четырёх пятибитных алфавитно-цифровых символа. Как и в телеграфе весь алфавит и цифры в 32 значения не влазил, поэтому два символа были отведены под «изменение таблицы символов».
Но самое странное как выглядела таблица текстовых символов, а выглядела она вот так:

0  00000   /   8    00010   %   16   00001   T   24   00011   O
1  10000   E   9    10010   D   17   10001   Z   25   10011   B
2  01000   @   10   01010   R   18   01001   L   26   01011   G
3  11000   A   11   11010   J   19   11001   W   27   11011   "
4  00100   :   12   00110   N   20   00101   H   28   00111   M
5  10100   S   13   10110   F   21   10101   Y   29   10111   X
6  01100   I   14   01110   C   22   01101   P   30   01111   V
7  11100   U   15   11110   K   23   11101   Q   31   11111   ? 

Здесь три колонки — номер по порядку, номер в бинарном коде и сам символ. Обратите внимание, что двоичные числа в команде Mark I было принято записывать с младшими разрядами справа!
Как видите никакой системы в расположении букв как будто бы нет. Но это вызвано тем, что эта битовая раскладка повторяет коды международного телеграфного кода тех лет:

Так вот программы составлялись этими вот буквенными кодами.
Вот как выглядит первый пример программы из книги Тьюринга:

// /CT/
E/ DSTI
@/ D//H
A/ R//P
:/ /C/S
S/ :CT/
I/ @CTI
U/ :C/S
%/ JS/P
D/ A/
R/ @/

Сразу не пугайтесь — тут всё просто. Первая колонка — это номер строки программы. / — это нулевой символ, E — это первый, @ — второй — посмотрите снова на таблицу. Т.е. в первой колонке просто выписаны по порядку числа от 0 до 10 в кодировке этой монументальной машины.
Сама программа находится во второй колонке — 20-битное число представлено четырьмя подряд идущими 5-битными буквами из которых первые две (10 бит) описывают номер ячейки памяти прошитый в инструкции, а последние две — код инструкции и так называемый код B-tube который позволяет делать индексации. Суровые манчестерские инженеры первые годы вот так вот и программировали — обложившись таблицами с перемешанными буквами, о чём см. ниже.

А вот теперь пойдём на страницу 55 руководства по второй ссылке в этом посте и посмотрим какие полезные приёмы и методики программирования пропагандировал в то время Алан Тьюринг:

Manoevring space / Место для манёвра

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

Do programming directly in teleprint code / Программируйте прямо в кодах телетайпа

Пишите программу сразу символами телетайпа!
It is never too soon to learn the meanings of the 64 functions [i.e., the opcodes].
Храните листочек с расшифровками букв опкодов под рукой и пользуйтесь постоянно и всего через неделю вы будете заглядывать в этот листочек очень редко.

Counting procedure / Отсчитывающая процедура

Очень часто в программировании возникает задача повторения одной и той же последовательности инструкций заданное количество раз.
Тьюринг приводит общую схему решения такой задачи в двух вариантах — while и repeat.

Discrimination by control transfer / Выбор с передачей управления

Здесь Тьюринг рассматривает задачу case от целого числа. Используя индексные регистры машины он показывает как сделать goto по массиву переходов.

Omission of counting / Пропуск повторов

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

Alternative entry / Альтернативная точка входа

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

Changing sign in the accumulator / Смена знака аккумулятора

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

Clearing the accumulator / Очистка аккумулятора

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

Electronic space economy measures / Меры по сохранению места в электронной памяти

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

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

6 комментариев

avatar
P.S.
Раскопал, что такая странная кодировка на самом деле не странная, а просто повторяет кодировку британского телеграфного кода тех лет — вставил картинку в статью.
avatar
Назвать Алана Тьюринга британским инженером — это, конечно, пять.

Но если учесть что Тьюринг — один из людей, сформировавший парадигму компьютерных вычислений вообще, я не уверен, что стоит сильно удивляться тому что мышление для современных компьютеров не особенно то и изменилось. Для смены парадигмы нужен ещё один Тьюринг.
avatar
Ну про инженеров — это я вообще ко всему коллективу работавшему над машиной обращался, там всё-таки согласно википедии 300000 человеко-часов было затрачено даже на предыдущую итерацию Mark I (Manchester Baby) у которого было всего 7 машинных команд (практически эзотерическая машина!) из которых арифметико-логические только вычитание и смена знака числа. Но вообще да, мозговой центр там был сплошь из профессоров и кандидатов наук.
avatar
Замечание об оставлении пустого места между строками много лет спустя повторилось в рекомендации нумеровать строки бейсик-программ числами, кратными 10 — при необходимости можно будет вставить новые строчки. :-)
avatar
Кстати, если вспоминать о бейсике в частности и ЯВУ в целом, то для Manchester Mark I/II было разработано несколько ЯВУ с общим названием Autocode: en.wikipedia.org/wiki/Autocode
Но забавным мне показался второй — Mark 1 Autocode, причём он довольно широко использовался, судя по википедии.
Пример программы:

  n1  =  201
  n2  =  301
  v99  =  0
7 v98  =  vn1 x vn2
  v99  =  v99+v98
  n1  =  n1+1
  n2  =  n2+1
  j7  ,  280 >= n1 

Что можно интересного сказать:
— одна операция — одна строка
— 18 целочисленных переменных с именами от n1 до n18
— столько вещественных переменных сколько было доступно прочей памяти с именами вида v1..v999
— оператор j7 переходит на строку пронумерованную как 7, после запятой пишется условие
— если нужно обращаться с ячейками памяти как с массивом, то используется конструкция vnx, например vn10 которая означает переменную v… с номером который хранится в переменной n10
Конечно это было прямо несколько шагов вперёд по сравнению с программирование в символах телетайпа.
avatar
Как дополнение:
Автокод, простой язык программирования; система команд некоторой условной машины, способной в качестве элементарных выполнять значительно более сложные операции, чем данная конкретная ЭВМ. Наиболее распространены А. типа 1:1, в которых основной элемент языка (оператор, строка) при переводе на языке цифровой вычислительной машины (ЦВМ) преобразуется в одну команду. С помощью А. типа 1:1 можно составить любую программу, которая возможна в системе команд вычислительной машины. Программирование на А. типа 1:1 эквивалентно программированию на языке ЦВМ, однако более удобно для человека и ускоряет работу примерно в 3 раза. А., отличные от А. типа 1:1, ориентируются не на систему команд ЦВМ, а на класс решаемых задач, значительно ускоряют работу по программированию, но не дают возможности получить программу такого же высокого качества, какое в принципе достижимо при программировании на языке ЦВМ или на А. типа 1:1. В А. (не типа 1:1) основной элемент языка (оператор) при переводе в код ЦВМ преобразуется, как правило, в совокупность нескольких команд. Указать резкую границу между А. и другими (более сложными) языками программирования невозможно. Примерами А. типа 1:1 могут служить А., разработанные в СССР для ЦВМ БЭСМ-6 и «Урал». Пример более сложного А. — А. типа «Инженер» для ЦВМ «Минск».

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

Во многих системах автоматического программирования А. служит промежуточным языком при переводе с другого языка программирования в код ЦВМ.

В. И. Собельман.

(Your text to link...)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.