программиста, в которых предложен ряд технологий оценивания. Есть обзор
опубликованных данных, подготовленный Моурином (Morin).4 Я приведу здесь
лишь несколько наиболее показательных результатов.



Рис. 8.1 Затраты на программирование как функция размера программы
Данные Портмана
Чарльз Портман (Charles Portman), менеджер отдела программирования ICL
- Computer Equipment Organization (Northwest) в Манчестере, предлагает свое
понимание проблемы, которое может оказаться полезным.
Он обнаружил, что его команды программистов отстают от графиков
примерно наполовину, т.е. каждое задание выполняется примерно вдвое дольше,
чем предполагалось. При этом оценки очень тщательно проводились группами
опытных экспертов, оценивавших в человеко-часах трудоемкость нескольких
сотен подзадач с помощью диаграмм ПЕРТ. Когда выявлялось отставание от
графика, он просил вести подробные ежедневные журналы использования времени.
Из них выяснилось, что ошибка оценок полностью объясняется тем, что его
команды использовали на программирование и отладку лишь 50 процентов
рабочего времени. Остальное время терялось из-за отказов машины, на
небольшие срочные посторонние задания, совещания, писание бумаг, дела фирмы,
болезни, личное время и т.д. Короче оценки исходили из нереалистичного
предположения о том, какая часть рабочего времени отводится непосредственно
работе.6
Данные Арона
Джоэл Арон (Joel Aron), менеджер IBM по системным технологиям в
Гейтерсберге, штат Мэриленд, изучал эффективность труда программистов во
время работы над девятью крупными системами (крупная соответствует более чем
25 программистам и 30000 операторов).7 Он классифицирует такие системы в
соответствии с интенсивностью взаимодействия между программистами (и частями
системы) и обнаруживает следующие величины производительности:
Очень слабое взаимодействие 10000 инструкций на человека в год
Некоторое взаимодействие 5000 инструкций на человека в год
Существенное взаимодействие 1500 инструкций на человека в год
Человеко-год здесь не учитывает поддержку и системное тестирование,
только разработку и программирование. При введении поправки с коэффициентом
два с целью учета системного тестирования эти цифры близко соответствуют
данным Харра.
Данные Харра
Джон Харр (John Harr), менеджер по программированию Electronic
Switching System, входящей в состав Bell Telephone Laboratories, сообщил о
своем собственном опыте и других известных ему данных в докладе на
Объединенной конференции по компьютерам весной 1969 года.8 Эти данные
приведены на рисунках 8.2, 8.3 и 8.4.
Наиболее поучителен и содержит больше данных рисунок 8.2. Первые два
задания являются, по преимуществу, управляющими программами, а два вторых -
языковыми трансляторами. Производительность измеряется в количестве
отлаженных слов за человеко-год. При этом учитывается время
программирования, отладки и системного тестирования. Неизвестно, учтены ли
затраты на планирование, поддержку машины, составление документации и т.п.



Рис. 8.2 Сводка по четырем важнейшим программным проектам,
осуществленным в ESS
Производительность разбивается на два класса: для управляющих программ
составляет около 600 слов на человека за год, для трансляторов - около 2200.
Обратите внимание, что все четыре программы приблизительно одного размера,
различие состоит в размере рабочих групп, продолжительности работы и
количестве модулей. Что является причиной, а что - следствием? Была ли
сложность причиной того, что для управляющих программ требовалось больше
людей? Или же большее число модулей и человеко-месяцев обусловлено большим
числом людей, привлеченных к работе? Была ли большая продолжительность
выполнения вызвана сложностью проблем или многочисленностью занятых людей?
Трудно сказать с уверенностью. Конечно, управляющие программы были более
сложными. Если оставить в стороне эти неопределенности, то цифры описывают
реальную производительность при создании больших систем, и потому
представляют ценность.
На рисунках 8.3 и 8.4 показаны некоторые интересные данные о
фактической скорости программирования и отладки в сравнении с прогнозом.
Данные OS/360
Опыт OS/360 подтверждает данные Харра, хотя данные по OS/360 не столь
подробны. В группах разработки управляющей программы производительность
составила 600-800 отлаженных команд в год на человека. В группах разработки
трансляторов производительность достигла 2000-3000 отлаженных команд в год
на человека. При этом учитывается планирование, тестирование компонентов,
системное тестирование и некоторые затраты на поддержку. Насколько я могу
судить, эти данные согласуются с результатами Харра.



Рис. 8.3 Предсказанная и фактическая скорость программирования



Рис. 8.4 Предсказанная и фактическая скорость отладки
Данные Арона, Харра и OS/360 дружно подтверждают резкие различия в
производительности в зависимости от сложности и трудности самой задачи. В
работе оценивания сложности я придерживаюсь той линии, что компиляторы втрое
хуже обычных пакетных прикладных программ, а операционные системы втрое хуже
компиляторов.9
Данные Корбато
Данные Харра и OS/360 относятся к программированию на языке
ассемблера. Есть немного публикаций относительно производительности
системного программирования с использованием языков высокого уровня. Корбато
(Corbato) из проекта MAC Массачусетского технологического института сообщает
о средней производительности 1200 строк отлаженных операторов PL/I на
человека в год при разработке операционной системы MULTICS (от 1 до 2
миллионов слов).10
Это число очень вдохновляет. Как у других проектов, MULTICS включает в
себя управляющие программы и языковые трансляторы. Результатом также
является системный продукт, отлаженный и документированный. Данные кажутся
сравнимыми в отношении видов исполненной работы. А производительность
повышается до средней величины между управляющими программами и
трансляторами в других проектах.
Но Корбато указывает количество строк за год на человека, а не слов!
Каждому оператору в его системе соответствует от трех до пяти слов кода,
написанного вручную! Из этого можно сделать два важных вывода:
- Производительность, измеренная в элементарных операциях, оказывается
постоянной, что кажется разумным, если учитывать, сколько времени нужно
думать над оператором, и сколько ошибок может в нем быть.11
- При использовании подходящего языка высокого уровня
производительность можно повысить в пять раз.12

    Глава 9. Два в одном


Автору стоит присмотреться к Ною и... поучиться на
примере Ковчега, как в очень маленькое пространство втиснуть очень много.
СИДНЕЙ СМИТ, "ЭДИНБУРГСКОЕ РЕВЮ"

Размер программы как стоимость
Какова стоимость программы? Если не считать времени выполнения, то
помять, занимаемая программой, составляет главные издержки. Это верно даже
для собственных разработок, когда пользователь платит автору существенно
меньше, чем стоит разработка. Возьмем интерактивную систему IBM APL. Плата
за ее использование составляет $400 в месяц. При работе она требует не
меньше 160 Кбайт памяти. У машины Model 165 ежемесячная аренда 1 Кбайта
памяти стоит около $12. Если пользоваться программой круглосуточно, то
месячная плата составит $400 за пользование программой и $1920 за память.
Если пользоваться системой APL лишь четыре часа в день, то месячная плата
составит $400 за пользование программой и $320 за использование памяти.
Нередко можно встретить человека, выражающего ужас по поводу того, что
в машине, имеющей 2 Мбайт памяти, под операционную систему может быть
отведено 400 Кбайт. Это столь же глупо, как ругать Боинг-747 за то, что он
стоит 27 миллионов долларов. Надо же спросить: "А что она делает?" Какую,
собственно, простоту в использовании и производительность (посредством
эффективного использования системы) получаешь за потраченные деньги? Нельзя
ли вложенные в аренду памяти $4800 в месяц израсходовать с большей пользой -
на другие аппаратные средства, программистов, прикладные программы?
Проектировщик системы отводит часть всех аппаратных ресурсов
программам, резидентно находящимся в памяти, если считает, что пользователю
это нужнее, чем сумматоры, диски и т.д. Нельзя критиковать программную
систему за размер как таковой, и в то же время последовательно
пропагандировать тесную интеграцию проектирования аппаратного и программного
обеспечения.
Поскольку размер определяет значительную долю того, во что обходится
пользователю системный программный продукт, изготовитель должен планировать
размер, контролировать его и разрабатывать технологии, уменьшающие размер,
подобно тому, как изготовитель аппаратной части планирует количество
деталей, контролирует его и разрабатывает методы сокращения количества
деталей. Как и для всякой цены, плох не большой размер как таковой, а
размер, не вызываемый необходимостью.
Управление размером
Для менеджера проекта управление размером является отчасти
технической, отчасти административной задачей. Чтобы устанавливать размеры
предлагаемых систем, необходимо изучать пользователей и используемые ими
приложения. Затем системы должны разлагаться на компоненты, для которых
определяются проектные размеры. Поскольку варьировать соотношением скорости
и размера можно лишь достаточно большими скачками, планирование размера
является непростым делом, требующим знания возможных компромиссов для каждой
части. Опытный менеджер сделает себе также "заначку", которую можно будет
использовать в процессе работы.
Все же при работе над OS/360 пришлось извлечь несколько горьких уроков,
несмотря на то, что все описанные меры были приняты.
Прежде всего, недостаточно установить размер памяти, нужно взвесить
размер со всех сторон. Большинство прежних операционных систем размещалось
на магнитных лентах, и большое время поиска на ленте не располагало к частой
загрузке программных сегментов. OS/360 располагалась на диске, как и ее
непосредственные предшественники - операционная система Stretch и дисковая
операционная системы 1410-7010. Ее создатели получили свободу легкого
обращения к диску. Первоначально это обернулось катастрофой для
производительности.
При определении размеров памяти компонентов мы не установили
одновременно бюджетов доступа. Как и следовало ожидать, программист,
выходивший за рамки определенной ему памяти, разбивал программу на оверлеи.
В результате и суммарный размер увеличивался, и выполнение замедлялось. Хуже
то, что наша система административного контроля не смогла это обнаружить.
Каждый программист сообщал, сколько памяти он использовал, и так как он
укладывался в задание, никто не беспокоился.
К счастью, вскоре настал день, когда заработала система моделирования
технических характеристик OS/360. Первые результаты показали наличие
серьезных проблем. Моделирование компиляции с Fortran H на машине Model 65 с
барабанами дало результат пять операторов в минуту! Анализ показал, что все
модели управляющей программы делали множество обращений к диску. Даже
интенсивно используемые модули супервизора часто обращались к диску, и
результат по звуку весьма напоминал шелест перелистываемой книги.
Первая мораль ясна: планировать нужно как размер резидентной части, так
и общий размер. Помимо планирования этих размеров нужно планировать и
количество обращений к диску для обратной записи.
Второй урок был аналогичен. Ресурсы памяти устанавливались прежде, чем
для каждого модуля было определено точное распределение памяти для функций.
В результате каждый программист, не укладывавшийся в размеры, искал, что из
его кода можно выкинуть через забор в память соседу. Поэтому буфера
управляющей программы стали частью памяти пользователя. Что хуже, так же
поступали все управляющие блоки, и в результате были полностью
скомпрометированы безопасность и защита системы.
Поэтому второй вывод тоже совершенно ясен: при задании размера модуля
нужно точно определить, что он должен делать.
И третий, более серьезный урок, который нужно извлечь из этого опыта.
Проект был слишком велик, а общение между менеджерами недостаточным, чтобы
многочисленные участники могли почувствовать себя добывающими зачетные очки
для команды, а не создателями программных продуктов. Каждый оптимизировал
свой личный участок, чтобы решить поставленные задачи, и мало кто
задумывался над тем, как это отразится на заказчике. Потеря ориентации и
связи представляют собой главную опасность для больших проектов. В течение
всей разработки системные архитекторы должны поддерживать постоянную
бдительность для обеспечения постоянной целостности системы. Однако такая
стратегия зависит от позиции самих разработчиков. Едва ли не главнейшей
функцией менеджера программного проекта должно быть воспитание позиции
заботы об общей системе, ориентировки на пользователя.
Технологии сбережения памяти
Никакое распределение ресурсов памяти и контроль не сделают программу
маленькой. Для этого требуется изобретательность и мастерство.
Очевидно, что чем больше функций, тем больше требуется памяти при том
же самом быстродействии. Поэтому первой областью, где нужно приложить
мастерство, является нахождение компромисса между функциональностью и
размером. Здесь мы сразу сталкиваемся с важной стратегической проблемой. В
какой мере этот выбор можно предоставить пользователю? Можно разработать
программу со многими факультативными функциями, каждая из которых требует
памяти. Можно сконструировать генератор, просматривающий список опций и
соответствующим образом адаптирующий программу. Но цельная программа,
соответствующая каждому отдельному списку опций, заняла бы меньше памяти.
Это как в автомобиле: если подсветка карты, прикуриватель и часы входят в
прейскурант как единая статья, их стоимость окажется ниже, чем если порознь
выбирать каждый из предметов. Поэтому проектировщику следует определить
степень детализации опций пользователя.
Если система проектируется для работы с памятью разного объема,
возникает другой важный вопрос. Диапазон приспособляемости нельзя сделать
произвольно широким - даже при разбиении программы на очень мелкие модули. В
маленькой системе большинство модулей перегружается. Значительная часть
резидентной памяти маленькой системы должна быть отведена для временной или
страничной памяти, в которую загружаются другие части. Ее размер
ограничивает размер каждого модуля. А разбиение функций на мелкие модули
влечет потери и производительность, и памяти. Поэтому в большой системе, где
временная память в двадцать раз больше, она лишь позволяет уменьшить
количество обращений. Из-за маленьких размеров модулей система все-таки
теряет в скорости и расходовании памяти. По этой причине эффективность
системы, которую можно построить их модулей маленькой системы, ограничена.
Второй областью приложения мастерства является нахождение компромисса
между памятью и быстродействием. Для отдельной функции увеличение памяти
влечет за собой рост быстродействия, что справедливо в удивительно широком
диапазоне величин. Этот факт делает возможным установление ресурсов памяти.
Чтобы облегчить своей команде поиск правильного соотношения между
памятью и производительностью, менеджер может сделать две вещи. Во-первых,
организовать обучение технике программирования, а не просто полагаться на
природный ум и предшествующий опыт. Это особенно важно, если машина или язык
новые. Особенности их эффективного использования нужно быстро изучить и
сделать общим достоянием, возможно, присуждая особые призы за освоение новой
техники.
Во-вторых, нужно понять, что у программирования есть технология и
компоненты нужно собирать из готовых частей. В каждом проекте должен иметься
набор хороших процедур или макросов для обработки очередей, поиска,
хеширования и сортировки, причем не менее чем в двух вариантах: одном
быстром, другом экономящем память. Разработка такой технологии является
важной задачей реализации, которую можно решать параллельно с разработкой
системной архитектуры.
Представление - суть программирования
За мастерством стоит изобретательность, благодаря которой появляются
экономичные и быстрые программы. Почти всегда это является результатом
стратегического прорыва, а не тактического умения. Иногда таким
стратегическим прорывом является алгоритм, как, например, быстрое
преобразование Фурье, предложенное Кули и Тьюки, или замена n2 сравнений на
n log n при сортировке.
Гораздо чаще стратегический прорыв происходит в результате
представления данных или таблиц. Здесь заключена сердцевина программы.
Покажите мне блок- схемы, не показывая таблиц, и я останусь в заблуждении.
Покажите мне ваши таблицы, и блок-схемы, скорей всего, не понадобятся: они
будут очевидны.
Примеры мощи, которой обладает представление, легко умножить. Я
вспоминаю одного молодого человека, занимавшегося созданием
усовершенствованного консольного интерпретатора для IBM 650. Ему удалось
вместить его в поразительно малое пространство благодаря разработке
интерпретатора для интерпретатора и пониманию того, что взаимодействие
человека с машиной происходит медленно и редко, а память дорога. Элегантный
маленький компилятор с Fortran фирмы Digitek использует особое очень плотное
представление кода самого компилятора, благодаря чему не требуется внешней
памяти. Время, которое тратится на распаковку кода, десятикратно окупается
за счет отсутствия ввода-вывода. (Упражнения в конце главы 6 книги Брукса и
Иверсона "Автоматическая обработка данных"1 включает подборку таких
примеров, как и многие упражнения у Кнута.2)
Программист, ломающий голову по поводу нехватки памяти, часто поступит
лучше всего, оставив в покое свой код, вернувшись назад и хорошенько
посмотрев свои данные. Представление - суть программирования.

    Глава 10. Документарная гипотеза


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

Технология, правила фирмы и традиции ремесла требуют выполнить
некоторое количество канцелярской работы по проекту. Менеджеру-новичку,
только что самому бывшему мастеровым, эта работа кажется совершенной помехой
и ненужным отвлечением, бумажным валом, грозящим захлестнуть его. По большей
части так и есть в действительности.
Однако понемногу он начинает понимать, что некоторая небольшая часть
этих документов заключает в себе значительную часть его административной
работы. Подготовка каждого из них служит главным поводом для сосредоточения
мысли и кристаллизации обсуждений, которые без этого длились бы вечно.
Ведение этих документов становится механизмом наблюдения и предупреждения.
Сам документ становится памяткой, индикатором состояния и базой данных для
составления отчетов.
Чтобы увидеть, как это должно работать в программном проекте,
рассмотрим некоторые документы, полезные и в другом контексте, и посмотрим,
можно ли сделать обобщения.
Документы для проекта разработки компьютера
Предположим, что разрабатывается компьютер. Какие важнейшие документы
должны быть разработаны?
Цели. Здесь описывается, какие потребности нужно удовлетворить, а также
задачи, пожелания, ограничения и приоритеты.
Спецификации. Это руководство по компьютеру плюс спецификации
технических характеристик. Это один из первых документов, составляемых для
нового продукта, и завершается он последним.
График.
Бюджет.
Это не просто ограничение, но один из наиболее полезных
менеджеру документов. Наличие бюджета заставляет осуществлять технические
решения, которых старались бы избежать, и, что еще важнее, служит выполнению
и разъяснению стратегических решений.
Организационная структура.
Пространственное расположение.
Оценка, прогноз, цены.
Они находятся в циклической взаимосвязи, что
определяет успех или провал проекта:



Чтобы сделать прогноз рынка, нужны технические характеристики и
установленные цены. Цифры прогноза вместе с заданным проектом числом
компонентов определяют оценку стоимости производства и долю расходов на
разработку и фиксированных затрат, приходящихся на одно устройство. Эти
расходы, в свою очередь, определяют цены.
Если цены ниже установленных, начинается радостная раскрутка спирали
успеха. Прогноз растет, стоимость одного устройства падает, а цены
опускаются еще ниже.
Если цены выше установленных, начинается раскрутка спирали катастрофы,
и все силы должны быть брошены на то, чтобы сломить ее. Нужно улучшить
технические характеристики и разработать новые приложения, чтобы поднять
рыночный прогноз. Издержки нужно снизить, чтобы получить более низкие
оценки. Напряженность такого цикла часто требует больших усилий маркетолога
и инженера.
При этом возможны забавные колебания. Я вспоминаю машину, у которой в
течение трех лет разработки каждые полгода счетчик команд устраивался то в
оперативной памяти, то вне ее. На одном этапе требовались чуть лучшие
характеристики, и счетчик делали на транзисторах. На следующем этапе
начиналась борьба за снижение стоимости, поэтому счетчик организовывался как
адрес в оперативной памяти. В другом проекте лучший известный мне менеджер
по инженерным проектам служил гигантским маховиком, гася своей инерцией
колебания, исходившие от маркетинга и менеджмента.
Документы для факультета в университете
Несмотря на огромные различия в целях и деятельности, критическое
множество для председателя факультета в университете составляет сходное
число сходных документов. Почти каждое решение декана, совета кафедры или
председателя является спецификацией или изменением следующих документов:
Цели.
Описание курса.
Требования к соискателю степени.
Предложения по исследовательской работе (и планы, при наличии
финансирования).
Расписание занятий и назначение преподавателей.
Бюджет.
Помещения.
Назначение руководителей для аспирантов.

Обратите внимание, что документы очень похожи на те, которые нужны для
компьютерного проекта: цели, спецификации продукта, распределение времени,
денег, места и людей. Только документы с ценами отсутствуют: этим занимается
законодательное собрание. Сходство не случайно - заботами всякой задачи
управления являются: что, когда, по какой цене, где и кто.
Документы для программного проекта
Во многих программных проектах работа начинается с совещаний, на
которых обсуждается структура; затем приступают к написанию программ. Однако
как бы ни был мал проект, менеджер поступит мудро, если сразу начнет
формализовать хотя бы минидокументы, которые послужат его базой данных. И он
обнаружит, что ему нужны, по большей части, те же документы, что и другим
менеджерам.
Что: цели. Здесь определяется, какие потребности должны быть
удовлетворены, а также задачи, пожелания, ограничения и приоритеты.
Что: спецификации продукта. Начинается как предложение, а кончается как
руководство и внутренняя документация. Важнейшей частью являются
спецификации скорости и памяти.
Когда: график.
По какой цене: бюджет.
Где: расположение помещений.

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