суббота, 26 ноября 2016 г.

Тепличные системы



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

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

Итак, о чем мечтает каждый автор? О том, чтобы ему дали карт-бланш ("чистый лист") на то, что бы разработать что-то в соответствии с лучшими практиками, технологиями и методологиями. Чтобы его не отвлекали в этой работе от стремления к идеалу, не торопили, заставляя "срезать углы". Дайте уже спокойно поработать! 

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

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

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



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

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

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

Талеб называет этот стиль мышления "платонизмом" - предпочтение фокусироваться на идеальном в противовес реальному. Забвение того факта, то реальность не совпадает с нашими представлениями о ней. Платонизм-по-Талебу создаёт ложное ощущение того, что мы понимаем, что происходит. Ложное ощущение уверенности в себе. Действительно, у нас же такие красивые и передовые модели, что может пойти не так?

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

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


Окей, это всё была философия и теория. Какие практические выводы из всего этого сделал для себя я?
"Top-down" подход
  1. Если видишь, как узкий круг лиц за закрытыми дверями принимает решения о реорганизации - жди беды. Оттуда вылезет какой-нибудь процессный монстр. Перед тем, как издохнуть он успеет помотать нервы сотрудникам. В такой ситуации надо либо сразу искать убежище, либо пытаться побиться в этот "узкий круг", чтобы заранее воздействовать на результат.
  2. Если решение разрабатывается в "top-down" подходе, где берут некую концепцию и пытаются "натянуть" её на текущую реальность - жди беды. Это один из тех методов, на которые надо наклеить предупреждающий знак - "никогда не пользоваться". 
  3. Бойся красивых, логичных и симметричных концепций - они приведут тебя в ад. 
  4. Если всё идет слишком гладко - жди беды. Скорее всего, выбран именно тот путь "проверки", который подвержен ошибке подтверждения. 
  5. Если кто-то даёт точные прогнозы - не верь им. Если таких прогнозов требуют от тебя - прояви скромность и честно скажи: "не знаю".
  6. Если не видишь в своей идее слабых мест, это не значит, что их нет. Это значит только то,что ты их просто не видишь. Включай "диверсионное мышление", обсуди её с самым вредным и критически настроенным коллегой, ищи failure stories схожие по ситуации. Ищи опровержения.
  7. Не надо расстраиваться, если "мешают работать", подсовывая "неудобные проблемы". Раз тебя достают, значит ты делаешь что-то нужное. Гораздо хуже, если о твоей работе не вспоминают. Скорее всего, ты уже оторвался от реальности, и неизбежное столкновение с ней будет болезненным.
Ничего нового не сказал, правда? Подвох в том, что все эти принципы просты в теории, но сложны на практике. Они идут против естественного для человека хода мыслительного процесса, они создают дискомфорт. В кутерьме и спешке, когда нет времени спокойно подумать, легко поддаться искушению и сделать ровно наоборот. Чтобы применять всё это на практике, необходимо иметь высокий уровень интеллектуальной дисциплины. По моему глубокому убеждению это вопрос личной компетенции каждого человека. Никакие навязанные извне процессы и практики не помогут, если этого нет внутри.

За сим прощаюсь с вами, спасибо за внимание.



суббота, 11 июня 2016 г.

Проект "Янтарь"

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

Что такое "Янтарь"?

Если коротко - то это мой собственный компьютер, придуманный с нуля, и реализованный на базе отладочной платы Terasic DE0 с чипом Altera Cyclone III. Он имеет собственную архитектуру, набор команд и некоторый набор инструментария разработчика и уже написанных программ. 

Компьютер "Янтарь" на фоне Большого Компьютера


Каковы характеристики компьютера на данный момент?
  • Разрядность процессора - 16 бит.
  • ОЗУ - 65536 16-битовых слов.
  • Тактовая частота: 160 КГц.
  • VGA-адаптер с монохромным текстовым режимом 80х30.
  • PS/2-клавиатура.
  • USB UART-модуль Wavesahre FT232 для связи с "большим" компьютером.
  • Инструментарий разработки: ассемблер "ALASM" (написан на C#)
  • Программная оболочка: программа-монитор "M3004" 

Зачем это нужно?

Этот проект имеет исключительно развлекательные и самообразовательные цели. Во-первых, я давно хотел разобраться в том, как работает компьютерное железо. Шутка ли, больше двадцати лет программировал, а до конца этого не понимал. Во-вторых, меня всегда немного завораживала старая компьютерная техника. Чтобы убить двух зайцев, я решил разработать с нуля собственный компьютер в духе классических домашних компьютеров эпохи процессора Intel 8080, его брата - Zilog Z80 и операционной системы CP/M.

Система

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




В принципе, тут должно быть всё понятно, отмечу лишь несколько моментов:
  1. Первые 16К ОЗУ реализованы на встроенных блоках памяти, находящихся на чипе ПЛИС. В них прямо в VHDL-коде "зашита" первоначальная программа, с котрой стартует компьютер. Для остальных 48К используется SDRAM-чип, расположенный на плате.
  2. Одна из кнопок на плате напрямую заведена на шину как сигнал аппаратного прерывания. Она используется для прерывания программы и вызова отладчика.
  3. На борту у платы есть микросхема электрического интерфейса для RS232, но у меня не нашлось под рукой нужных разъемов, поэтому я купил отдельный UART<->USB адаптер Waveshare FT232 и подсоединил его через GPIO-выходы на плате.
  4. Я пока не освоил запись в Flash-память, поэтому использую этот чип как ПЗУ. 
Системная шина устроена достаточно примитивно и состоит из следующих сигналов:
  • Данные - 16 бит.
  • Адрес - 16 бит.
  • Сигнал чтения.
  • Сигнал записи.
  • Сигнал выбора пространства ввода/вывода.
  • Сигналы запроса на прерывание - 16 бит.

Процессор

Процессор построен по одношинной архитектуре и управляется микрокодом. Пользователю напрямую доступны 8 регистров общего назначения (R0 - R7), а так же два спец. регистра: 
  • SP (stack pointer) 
  • BP (base pointer) 
последний указывает на фрейм текущей подпрограммы.

Система команд выполнена в духе так называемых "load/store" архитектур. Практически все операции выполняются над значениями в регистрах или над регистром и константой. Команды load/store поддерживают немного более широкий список режимов адресации:
  • Абсолютный адрес: ld R0, [0FC00]
  • Адресация через регистр: ld R0, [R1]
  • Адресация через регистр + константа: ld R0, [R1 + 100]
  • Адресация через регистр + регистр:     ld R0, [BP + R1]
Для косвенной адресации могут применяться любые регистры из вышеперечисленных.

Микрокод процессора похож на примитивный ассемблер и выполняется строго последовательно, поэтому такты расходуются достаточно неэффективно. Вот так выглядит мирокпрограмма операции сложения регистра с константой:
ADDC:
INI OA, OP_ADD; // Установка кода операции АЛУ
FETCH;          // Вычитка слова с константой
MOV O1, REG1;   // Инициализация первого операнда
MOV O2, DATA;   // 
Инициализация второго операнда
MOV REG1, RES;  // Запись результата
END;
Как видно, пять микрокоманд. С учётом дополнительных издержек - 7 тактов. Такая чудовищная неэффективность процессора есть результат сознательного выбора - чем проще, тем лучше.

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

Ассемблер

Ещё в самом начале работы над виртуальной версией процессора я быстро понял, что программирование в машинных кодах - это для меня слишком брутально и хардкорно. Тогда я написал первую версию ассемблера на VBA. С тех пор я два раза переписал его на C# и теперь он приобрел достаточно законченный и функциональный вид. Вот так выглядит процедура вывода строки на экран:
subroutine print(message)
    push    R0
    push    R1
    ld      R0, [BP + message]
loop:
    ld      R1, [R0]
    cmp     R1, 0
    je      [exit]
    out     R1, [TTY]
    inc     R0
    jmp     [loop]
exit:
    pop     R1
    pop     R0
    return
end
Ассемблер написан с использованием парсера Sprache, который позволил достаточно быстро и без заморочек описать синтаксис. Правда, как оказалось, для более сложных случаев он не годится, поэтому я сейчас гляжу в сторону Irony.

Монитор

Венцом работы на данный момент является программный монитор "M3004" (назван так потому что эту версию я начал разрабатывать 30 апреля). По мере того, как я переходил от разработки аппаратной части к программной, всё больше появлялась потребность в какой-то оболочке, которая бы облегчила отладку и обеспечила бы базовый инструментарий для управления компьютером. Так постепенно появился и стал развиваться Монитор. Что умеет монитор делать сейчас?
  • Загружать и запускать программы из ПЗУ, а так же из последовательного порта
  • Прерывать исполнение программы по аппаратной кнопке, исследовать и модифицировать состояние памяти и регистров.
  • Выполнять программу по шагам.
  • Ставить точки останова.
  • Читать и писать в порты ввода/вывода


На следующей картинке видно, как была загружена программа, и установлена точка останова. После того, как програма "налетает" на неё, управление  предаётся монитору, где можно проинспектировать состояние и продолжить отладку. Монитор занимает верхние 4К слов адресного пространства, оставляя всю нижнюю память для отлаживаемых программ. Для прерывания программы можно использовать аппаратную кнопку на плате.
Всего Монитор - это ~22 килобайта кода на ассемблере, которые в итоге собираются в ~3500 машинных слов. Потребление памяи машинным кодом оказалось несколько выше, чем я ожидал, но я пока не оптимизировал код.

Заключение

По результату полугодовой работы получилось достаточно функциональный компьютер, который демонстрирует свою работоспособность. Схема, конечно, получилась не без огрехов которые регулярно всплывают в ходе её доработки. Оно и понятно - я действую больше наугад, чем "по книге". Основной нерешённой проблемой для меня остаётся создание устройства долговоременного хранения "на борту" - я так и не смог пока научиться писать в Flash-чип, да и с ним есть определённые проблемы. Подумываю о том, чтобы прикупить дисковод и дискеты и научиться взаимодействовать с ними. Другое направление деятельности - развитие инструментария. Программировать на ассемблере не так уж и весело, хочется реализовать язык высокого уровня. Ну и, наконец, трансформировать Монитор в полноценную операционную систему по типу CP/M



вторник, 3 мая 2016 г.

История появления IBM PC


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

В статье была историческая справка о том, как именно в недрах IBM зарождался и шёл этот проект. Я её прочитал, не ожидая для себя ничего интересно. Между тем, я нашёл там весьма любопытную и поучительную историю, которая может кое-чему научить.

Когда танцору не яйца мешают...

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

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

Тащи динамит, строить будем

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

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

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

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

Самобытный Agile?

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

Dave Bradley, изобрёл
"три весёлые клавиши"
Ctrl-Alt-Del
About a dozen people made up the first development team, recalls Dave Bradley, who wrote the interface code for the new product. "For a month, we met every morning to hash out what it was this machine had to do and then in the afternoons worked on the morning's decisions. We started to build a prototype to take — by the end of the year — to a then little-known company called Microsoft." The team beat that deadline. The engineers were virtually finished with the machine by April 1981, when the manufacturing team took over.
Хотя это и не сказано нигде явно, вырисовывается картина того, что сейчас бы назвали "гибкой разработкой".

Итог

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

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

Так же это история о том, как настоящий прорыв был сделан небольшой, но сфокусированной и компетентной группой в рамках большой компании. Ведомая Уильямом Лоувом группа насчитывала 12 человек. В неё попадали добровольцы, увлеченные новым проектом

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


пятница, 25 марта 2016 г.

Запись в дневнике после удаления зуба мудрости

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


Как и все разработчики, однажды я был очарован передовыми идеями объектно-ориентированного подхода, паттернами "Банды четырёх", компонентной объектной моделью и мантрами "все есть объект". В институте нас учили, что ООП - это Единственный Правильный Путь Программирования, иные парадигмы отметались как устаревшие и недостаточно продвинутые. Объектная истерия тогда изрядно захлестнула индустрию. Помню, как одно время сильно пиарили ООБД, которые должны были похоронить РСУБД как класс, но почему-то не взлетели. Я был очарован, но одновременно и подавлен: у меня никак не получалось достичь гармонии. Мои системы классов были запутаны, я тратил часы и дни пытаясь придумать идеальную иерархию, а потом тратил вдесятеро больше времени, борясь с полученными монстром. От этого я натурально впадал в депрессию и не хотел возвращаться к своим программам.

Первой вехой на пути к освобождению ума стало открытие, что в процедурном стиле можно написать очень хороший код, который будет понятен, расширяем и весьма сопровождабелен. Это заставило меня пересмотреть свои взгляды. Оказалось, что качество кода и пути его достижения не зависят от выбранной парадигмы. Они фундаментальны и приходят с опытом. Если ты делаешь BDUF при отсутствии исчерпывающих вводных, то ты дурак вне зависимости от того, какое у тебя любимое ключевое слово - "class" или "procedure". Или даже "predicate". Плохо ли ООП? Ничуть! Проблема не в парадигме как таковой, а в людях, которые уверовали в её чудодейственную силу решить все наши проблемы. И лично во мне, поскольку я тоже уверовал и тратил время на достижение "объектной чистоты" вместо того, что бы обучаться фундаментальным навыкам, критичным для своего дела.


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

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

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

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

Плох ли Agile? Ничуть! Это хороший и полезный инструмент для ряда задач, но он не заменяет фундаментальных навыков, необходимых для работы. Наоборот, он весьма требователен к их наличию.


Этот опыт изменил мой подход к работе: от развития "сверху вниз" я стал переходить к развитию "снизу вверх". Это означает, что я не занимаюсь внедрением готового процесса ("с понедельника живём по скраму"), а занимаюсь систематическим поиском и решением конкретных проблем, а так же развиваю в себе и своих коллегах базовые навыки, составляющие тот самый фундамент. Это не так гламурно, как размахивать флагом с новым модным названием. Это долгая и кропотливая работа, но эти вложения окупаются. Agile, Scrum, PBMOK, Теория ограничений Голдратта и прочие полезные вещи лежат у меня в загашнике и применяются по мере необходимости, когда я считаю их подходящими к ситуации.

За сим свои бухтения прекращаю.

понедельник, 8 февраля 2016 г.

Как я придумал свой процессор 2: Из виртуальности в реальность

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

Решив, что останавливаться на достигнутом ещё рано, я стал думать, что делать дальше. Перебрав несколько вариантов я решил, что надо от симулированных схем переходить к настоящим. В качестве "мягкого" варианта работы с железом я выбрал экспериментирование ПЛИСом. В поисках подходящий платы я перебрал много вариантов и в итоге я выбрал для себя Terasic DE0 с чипом Cyclone III. Этот набор имеет достаточно мощный чип и хороший набор интегрированных портов и вспомогательных устройств (ОЗУ, Flash, SD-слот, кнопки, светодиоды)

ПЛИС: Начало

Цель - сделать свой процессор на ПЛИС - более амбициозная и более сложная, чем нарисовать его в программе-симуляторе. Помимо того, что надо осваивать новый язык (VHDL) и инструментарий (Altera Quartus II), здесь надо было думать о некоторых вещах, которые в симуляторе уже были сделаны за меня. Например, самому реализовать консольный ввод/вывод при помощи VGA-монитора и PS/2-клавиатуры.

Чтобы ускорить процесс, я искал и применял готовые наработки:
  1. Прототип текстового VGA-контроллера (нашёл на сайте проекта "Марсоход").
  2. Контроллер PS/2 клавиатуры вместе с ASCII-декодером: тут.
  3. Простейший SDRAM-контроллер.
Все эти компоненты для в той или иной мере перерабатывал, тестировал, склеивал друг с другом в тестовых конфигурациях. После этих экспериментов с этими почти готовыми модулями настал момент написать с нуля самый важный модуль - собственно, процессор.

Через тернии

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

Другой проблемой, над которой изрядно пришлось поломать голову, стала проблема взаимодействия двух схем, синхронизированных разными тактовыми частотами. Проявлялась она в том, что периодически зависал мой видеоконтроллер, который работал на частоте 25 МГц, но взаимодействовал с шиной низкой частоты (сотни герц). Разрешение этой проблемы потребовало чтение многих статей, изучения новых для меня понятий и концепций (например, "метастабильное состояние", "домен синхронизации"). Итог - вставленный за десять минут между шиной и контроллером асинхронный FIFO-буфер из библиотеки Altera Quartus II решил проблему. Но шёл я к этому тривиальному ответу долго...

Результат

Сказать по правде, пару раз руки опускались. Возникала мысль, мол, а не взялся ли я за проблему не по моим способностям? Но благодаря проявленной моральной и интеллектуальной стойкости мне удалось продраться через возникавшие по пути проблемы. Результатом стала точная логическая копия второго процессора на ПЛИС, бинарно совместимая с оригиналом. Даже микрокод из оригинала был повторно использован без изменений. В подтверждение скриншот виртуального терминала и фото реального монитора с выводом программы самотестирования:


Естественно, что программа, загруженная в обе реализации была одной и той же. Полученная система имеет следующие характеристики:
  1. Ширина машинного слова: 16 бит.
  2. Ширина адреса: 16 бит, максимально адресуемая память - 128К (65536 двухбайтовых слов). Отдельные байты не адресуются.
  3. Ввод-вывод с отображением на адресное пространство.
  4. ОЗУ на чипе ПЛИС - 16К (8192 двухбайтовых слова).
  5. Ввод: PS/2 клавиатура.
  6. Вывод: текстовый VGA-терминал, матрица 80х30 символов. Знакогенератор использует прошивку от CGA-адаптера с шрифтом 8х8 точек (эх, ностальгия!).
  7. Потребленные ресурсы ПЛИС: 2147 логических модуля (примерно 15% от ресурсов чипа).

Итог


Успешный прогон программы самотестирования - значительная веха моего домашнего "процессорного" проекта. Однако почти всё ещё впереди: видеотерминал надо превратить в полноценный адаптер с графическим режимом, для ОЗУ использовать SDRAM-чип, установленный на плате, освоить работу с Flash-чипом и SD-слотом, установленными на плате. После этого можно писать свой монитор и совершенствовать процессор, который ещё бесконечно далёк от совершенства.



воскресенье, 31 января 2016 г.

Холакратия на авианосце?

Продолжая свое исследование опыта построения организационных структур у военных, я наткнулся на очень любопытную публикацию из журнала "Naval War College Review" от 1987-го года. Сама статья называется "The Self-Designing High-Reliability Organization: Aircraft Carrier Flight Operations at Sea"

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



"The job of this ship is to shoot the airplanes off the pointy end and catch them back on
the blunt end. The rest is detail."
-- Carrier commanding officer


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

Итак, какие основные особенности авторы выделили в ходе своего исследования?

Живая культура.
Несмотря на то, что армия считается исключительно зарегулированным институтом, в котором на каждый чих есть свой SOP (Standard operating procedure), в реальности записанного в инструкциях категорически недостаточно для того, чтобы успешно осуществлять деятельность. Конкретика уточняется на месте самими командами кораблей, подгоняется под конкретные условия и постоянно эволюционирует. В результате даже у кораблей одного класса сложившиеся порядки и протоколы взаимодействия могут серьезно различаться. Так же это означает, что новый корабль, укомплектованный свежими кадрами не готов к развертыванию до тех пор, пока его команда не научится его применять. Большинство выработанных "на месте" правил существует в виде живой неписанной культуры, которая поддерживается за счет постоянного применения на практике. Это приводит к тому, что без поддержки непрерывности действий эта культура быстрое теряется и нуждается в восстановлении. Если корабль на долгое время выбывает из строя (например, из-за кап.ремонта), то после введения в строй ему нужно существенное время для восстановления культуры, необходимой для обретения боеспособности.

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

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

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


Почему это может быть интересно нам?

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

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

"Главный секрет атомной бомбы был в том, что она возможна"

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

суббота, 9 января 2016 г.

Как я придумал свой процессор.

Я давно работаю в индустрии разработки программного обеспечения. Десять лет я увлекался программированием как хобби, ещё десять лет был программистом по профессии. Хотя мне доводилось программировать на достаточно низком уровне, одно оставалось для меня загадкой: каким образом из простых логических элементов получается машина, способная последовательно менять своё состояние и что-то делать, руководствуясь заданной программой. Не смотря на то, что я читал материалы о том, как устроены процессоры, полного понимания я так и не получил, всё равно оставалась в этом какая-то тайна и магия. Воспользовавшись праздниками я решил восполнить этот пробел, руководствуясь принципом: "чтобы что-то понять, надо научиться это сделать самому".

Для экспериментов я использую программу Logisim - очень удобное и наглядное средство для моделирования дискретных схем. 

Калькулятор

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



Процессор 1.0

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

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

Процессор 2.0

Попытки написать программы для Процессора 1.0 выявили примитивность и непрактичность его набора команд, поэтому целью разработки второго процессора стала поддержка полноценного набора команд, который позволит писать осмысленные программы. В частности, необходимым я счёл:
  1. Условные переходы
  2. Косвенная адресация (доступ к ячейке, адрес которой хранится в регистре)
  3. Работа со стеком (команды push/pop).
  4. Поддержка подпрограмм (команды call/ret)
Составив список нужных команд я засел за разработку и через несколько дней получил первые работающие варианты. Сегодня компьютер выполнил "Hello, World". Сейчас процессор выглядит так:
Некоторые характеристики:
  • Разрядность регистров, шины данных и адреса: 16 бит.
  • Память адресуется только 16-битными словами
  • Микрокодовая архитектура процессора реализующая 60 команд (RISC). 
  • Микрокод составляет 255 24-битных слова.
  • Восемь регистров общего назначения (R0-R7)
  • Прямая и косвенная адресация через регистры
  • Косвенная адресация со смещением через два спец. регистра: SP (stack pointer) и OP (object pointer). 
  • Объединенная шина памяти и ввода-вывода.
  • Одношинная микроархитектура
  • Средняя длительность выполнения команды - 4 такта.
Процессор сделан по максимально простой одношинной архитектуре, которая даёт процессору хорошую гибкость, но делает его чрезвычайно медленным в исполнении команд. Пока я с этим смирился, так как простой процессор позволяет легко добавлять новые команды, просто расширяя микрокод.

При разработке процессора очень удобным инструментом оказался Excel. В нем я вел документацию, составлял микрокод и даже реализовал на VBA простой ассемблер. Вот так выглядит программа "Hello, World" и с генерированный ассемблером код:


Программа Logisim оказалась удивительно хорошо совместима с Excel: сгенерированный двоичный код прекрасно переносится в Logisim через copу/paste. 

Заключение

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

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

Конечная цель моих игр с Logisim - создание простого виртуального компьютера и базового ПО к нему. Меня сильно вдохновляют советские домашние компьютеры 80-ых (например, ЮТ-088), которые я выбрал для себя как некий идеал конечного результата. К этой цели и буду двигаться по мере наличия вдохновения и свободного времени, так что ждите новых публикаций по этой теме :)