Литмир - Электронная Библиотека
A
A

25.2.2. Принципы

 

Программирование. Принципы и практика использования C++ Исправленное издание - _003.png
 При создании программ для встроенных систем существует опасность, что в погоне за высокой производительностью и надежностью программист станет использовать исключительно низкоуровневые средства языка. Эта стратегия вполне оправдана при разработке небольших фрагментов кода. Однако она легко превратит весь проект в непролазное болото, затруднит проверку корректности кода и повысит затраты времени и денег, необходимых для создания системы.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Как всегда, наша цель — работать на как можно более высоком уровне с учетом поставленных ограничений, связанных с нашей задачей. Не позволяйте себе опускаться до хваленого ассемблерного кода! Всегда стремитесь как можно более прямо выражать ваши идеи в программе (при заданных ограничениях). Всегда старайтесь писать ясный, понятный и легкий в сопровождении код. Не оптимизируйте его, пока вас к этому не вынуждают. Эффективность (по времени или по объему памяти) часто имеет большое значение для встроенных систем, но не следует пытаться выжимать максимум возможного из каждого маленького кусочка кода. Кроме того, во многих встроенных системах в первую очередь требуется, чтобы программа работала правильно и достаточно быстро; пока ваша программа работает достаточно быстро, система просто простаивает, ожидая следующего действия. Постоянные попытки написать несколько строчек кода как можно более эффективно занимают много времени, порождают много ошибок и часто затрудняют оптимизацию программ, поскольку алгоритмы и структуры данных становится трудно понимать и модифицировать. Например, при низкоуровневой оптимизации часто невозможно оптимизировать использование памяти, поскольку во многих местах возникает почти одинаковый код, который остальные части программы не могут использовать совместно из-за второстепенных различий. Джон Бентли (John Bentley), известный своими очень эффективными программами, сформулировал два закона оптимизации.

• Первый закон: “Не делай этого!”

• Второй закон (только для экспертов): “Не делай этого пока!”

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

25.2.3. Сохранение работоспособности после сбоя

Представьте себе, что вы должны разработать и реализовать систему, которая не должна выходить из строя. Под словами “не выходить из строя” мы подразумеваем “месяц работать без вмешательства человека”. Какие сбои мы должны предотвратить? Мы можем не беспокоиться о том, что солнце вдруг потухнет или на систему наступит слон. Однако в целом мы не можем предвидеть, что может пойти не так, как надо. Для конкретной системы мы можем и должны выдвигать предположения о наиболее вероятных ошибках. Перечислим типичные примеры.

• Сбой или исчезновение электропитания.

• Вибрация разъема.

• Попадание в систему тяжелого предмета, приводящее к разрушению процессора.

• Падение системы с высоты (от удара диск может быть поврежден).

• Радиоактивное облучение, вызывающее непредсказуемое изменение некоторых значений, записанных в ячейках памяти.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _003.png
 Труднее всего найти преходящие ошибки. Преходящей ошибкой (transient error) мы называем событие, которое случается иногда, а не каждый раз при выполнении программы. Например, процессор может работать неправильно, только если температура превысит 54 °C. Такое событие кажется невозможным, однако однажды оно действительно произошло, когда систему случайно забыли в заводском цехе на полу, хотя в лаборатории ничего подобного никогда не случалось.

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

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Знание предметной области, т.е. сведения о системе, ее окружении и применении, играют важную роль при разработке и реализации систем, устойчивых к ошибкам. Здесь мы коснемся лишь самых общих вопросов. Подчеркнем, что каждый из этих общих вопросов был предметом тысяч научных статей и десятилетних исследований.

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

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

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

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 • Быстрый способ выйти из неправильно работающей программы. Составляйте системы из модулей. В основу обработки ошибок должен быть положен модульный принцип: каждый модуль должен иметь свою собственную задачу. Если модуль решит, что не может выполнить свое задание, он может сообщить об этом другому модулю. Обработка ошибок внутри модуля должна быть простой (это повышает вероятность того, что она будет правильной и эффективной), а обработкой серьезных ошибок должен заниматься другой модуль. Высоконадежные системы состоят из модулей и многих уровней. Сообщения о серьезных ошибках, возникших на каждом уровне, передаются на следующий уровень, и в конце концов, возможно, человеку. Модуль, получивший сообщение о серьезной ошибке (которую не может исправить никакой другой модуль), может выполнить соответствующее действие, возможно, связанное с перезагрузкой ошибочного модуля или запуском менее сложного (но более надежного) резервного модуля. Выделить модуль в конкретной системе — задача проектирования, но в принципе модулем может быть класс, библиотека, программа или все программы в компьютере.

347
{"b":"847443","o":1}