О культуре

«Единственная проблема Microsoft в том, что у них абсолютно нет вкуса…. …они не привносят в свои продукты культуру» С. Джобс

Черт! Как это одновременно и банально и актуально!

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

Рубрика: Uncategorized | Оставить комментарий

itow

Отличный вопрос для собеседования:

«Напишите реализацию функции, преобразующую целое число типа int в строку в формате Unicode.»

Тонкость в том, что алгоритм практически ничем не отличается от преобразования в ASCII строку, но, чтобы это сообразить, надо хоть немножко знать Unicode.

Рубрика: Uncategorized | 1 комментарий

swprintf %s

swprintf(ws, size, «%s», string);

Течет память, в размере длины строки, если строка string имеет размер больше 30К. Обнаружено на embedded linux (с ядром 2.6.18), но, как оказалось, проблема существует и в самых последних версиях, например в Ubuntu 11.04 со всеми обновлениями.

Рубрика: Uncategorized | Оставить комментарий

Две ошибки стоимостью в два дня отладки

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

Вот первая ошибка:
// создаем массив векторов
std::vector<std::vector<SomeStruct> > theVector;
std::vector<SomeStruct> emptyVector;
for (int i = 0; i < 100; i++)
  theVector.push_back(emptyVector);
Я рассуждал примерно так: vector — это объект, хранящий указатели на область памяти, где фактически хранятся данные. Но, для пустого вектора, эти указатели будут равны NULL. А значит, мы можем многократно копировать пустой вектор. Но STLport не был бы STLport’ом, если бы все было так просто. Оказывается, vector в одном из полей хранит указатель на самого себя. И инициализируется этот указатель во время работы конструктора. Поэтому правильно создавать вектор векторов так:
// создаем массив векторов
std::vector<std::vector<SomeStruct> > theVector;
for (int i = 0; i < 100; i++)
  theVector.push_back(std::vector<SomeStruct>());
Теперь о второй ошибке. 
std::vector<SomeStruct>& v = theVector[index1];
// поработали немного с этим вектором, потом понадобился другой
v = theVector[index2];
Все, приплыли! Так делать категорически нельзя! Только я это понял через день отладки, когда заменил ссылки на указатели, которые почему-то 🙂 работали правильно:
std::vector<SomeStruct>* pv = &theVector[index1];
pv = &theVector[index2]; // а вот так делать можно!
Важное отличие ссылки от указателя заключается в том, что в ссылочную переменную адрес объекта заносится один и только один раз — при ее инициализации. Все! Любые другие присваивания ссылочной переменной — это присваивания объекту, хранящемуся по этому адресу. Но с точки зрения синтаксиса, правая и левая части выглядят одинаково в обоих случаях, однако действия, выполняемые при этом, принципиально разные. Все зависит от того, находится ли слева от левой части тип данных или нет.
Рубрика: Uncategorized | 3 комментария

Опасные ситуации

Нейл: Какие тяжелые проблемы были обнаружены на Земле, до того, как экспедиция отправилась в космос?

Делиман: На Земле обнаружили много проблем, даже еще в Wind River. Я бы не сказал, что все они были тяжелыми, хотя некоторые были нетривиальными.

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

Нейл: Это было самой трудной проблемой, с которой вы столкнулись при подготовке экспедиции?

Делиман: Было две проблемы: на Mars Pathfinder приоритеты обрабатывались в обратном порядке, а на MER была проблема с файловой системой. Обе были решены одним из наиболее талантливых инженеров, с кем мне когда-либо приходилось работать. Я думаю, что лучшее что сделал Гленн Ривз (эксперт в ПО полета для экспедиции Mars Pathfinder) — это объяснил что было неправильно и как это было исправлено (http://research.microsoft.com/~mbj/Mars_Pathfinder/Authoritative_Account.html) (Замечание: Майк, который часто упоминается в этом документе — это Майк Джонс из Микрософт, Майк Делиман — cотрудник Wind River).

Нейл: Очевидно, что у вас был сумасшедший дом, когда один из аппаратов стал неуправляемым на несколько недель. Что произошло и почему потребовалось так много времени на устранение неполадок? Было ли это той проблемой, которую легко исправить как только установишь причину? Или же это была действительно сложная ситуация, требующая много усилий для ее устранения?

Делиман: Это было точно непростая задача обнаружить, что произошло в данном случае и исправить ситуацию.

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

Хотя я напрямую не был связан с исправлением данной проблемы, я помогал команде насколько мог. Например, меня позвали на помощь буквально через 20 минут после приземления Оппотьюнити на Марс. Здесь потребовалось исследование исходного когда и общение с экспертами из трех временных зон: Япония, Калифорния и кратер Гусева (место, куда приземлился Спирит), а также приходилось постоянно иметь при себе все необходимые данные. Я работал в выходные, просыпался по три раза в день, чтобы связаться с необходимыми людьми, прерывался только чтобы поесть, поспать, принять душ и позаботиться о своих собачках.

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

Нейл: Оказал ли космический корабль какое-либо влияние на операционную систему? То, что вы изучили, работая с НАСА и лабораторией реактивных двигателей, как-нибудь отразилось в исходном коде?

Делиман: Некоторые вещи, которые мы исправляли для космических экспедиций, оказались и в базовом пакете. Например, вместе с несколькими инженерами из поддержки Wind River, мы исправили некоторые математические функции для космических кораблей; полученные подпрограммы были настолько же точны, как и версии стандарта IEEE 754, но работали немного быстрее.

Нейл: Как вы думаете, НАСА когда-нибудь перейдет на операционные системы с открытым исходным кодом для своих космических экспедиций?

Делиман: Я бы не исключал такой возможности, но дело в том, что когда ты работаешь с аппаратурой, стоимостью милиарды долларов и тратишь на это множество человеко-лет, ты хочешь работать с тем, что ты хорошо знаешь. Например, посмотрите на процессор Rad6000. Это 32-битный чип, который работает на частоте 20 мегагерц, и который был вершиной технологической мысли где-то в 1990-х годах. Он может использовать ограниченный объем памяти, и эта память является довольно медленной по сегодняшним меркам. Это в лучшем случае реликвия, по сравнению с сегодняшними процессорами, которые работают в сотни раз быстрее.

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

Рубрика: космос | Оставить комментарий

Жесткие ограничения

 Нейл: Были ли какие-нибудь особые архитектурные проблемы или сложные требования при разработке операционной системы или приложений для MER? Приходилось ли прибегать к каким-либо уникальным техническим приемам по причине того, что целевая платформа — это космический корабль, скажем, особым подходам к удаленной отладке?

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

В лаборатории реактивных двигателей нашли методы получения отладочной информации от системы, когда создавали Mars Pathfinder. Это было сделано благодаря гибкости операционной системы и знанию того, как работает система (прикладной двоичный интерфейс для процессора — ABI). Чтобы этого достичь, лаборатории потребовался доступ ко всем исходным кодам и возможность компилировать систему из них самостоятельно. Это ключевой момент — он дает команде инженеров возможность исследовать абсолютно все компоненты системы. Вообще говоря, программное обеспечения, поставляемое Wind River, не было предназначено для этого. Мне пришлось потрудиться, пока я добился, чтобы ПО, поставляемое для MER можно было использовать так, как это было необходимо для нас, включая полную перекомпиляцю своими силами при необходимости.

Нейл: Как много кода было написано в лаборатории реактивных двигателей по сравнени с тем, что было написано в Wind River?

Делиман: Операционная система и ее ядро занимают менее 2 мегабайт; весь остальной код, а также данные в конечном счете превышали 30 мегабайт.

Нейл: Какие инструменты вы использовали при написании кода для космического корабля?

Делиман: Самыми распространенными "инструментами", на мой взгляд, являются инженеры. У каждого специалиста есть своя предпочитаемая платформа (Sun или PC), редакторы (vi, Emacs, собственный или еще какой-либо) и методология.

Нейл: Насколько контроль качества кода, который отправлялся в НАСА отличался от того, что получали остальные заказчики?

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

Нейл: НАСА повторно тестирует все, что получает от поставщика ПО?

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

Нейл: Чем операционная система, поставляемая в НАСА, отличалась от того, что получали остальные клиенты?

Делиман: В случае с MER, она была уникальной. Было внесено много исправлений и дополнений для телескопа Спитцер (также известного как космический инфракрасный телескоп — SIRFT); другие расширения были разработаны, чтобы минимизировать число изменений в операционную систему. Эти изменения включали в себя вычисления тригонометрических функций с повышенной точностью, улучшенную подсистему ввода-вывода, и исправляли несколько ошибок. Все эти расширения были внесены в ветку, предназначенную для MER. Этот код был затем модифицирован, чтобы скомпилировать его с новейшими версиями компиляторов (включая обновленный front-end для С++), заново протестирован и отправлен команде MER. [Подробную информацию относительно телескопа Спитцер можно найти здесь http://www.spitzer.caltech.edu/]

Код для MER также был адаптирован для сборки его на стороне клиента, не используя инфрмаструктуру Wind River. Это очень нестандартная практика.

Нейл: Были ли вопросы относительно безопасности ПО, предназначенного для космоса? Кто-нибудь пытался "взломать" его?

Делиман: Проблема заключается в том, что единственным способом связи с космическим кораблем являются антенны НАСА. Довольно трудно создать антенну, размером с футбольный стадион, на заднем дворе, не привлекая к себе внимания.

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

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

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

Нейл: Какие специальные трюки применялись чтобы справиться с проблемами в ПО, которое находится в нескольких световых минутах отсюда?

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

Последняя глава: "Опасные ситуации"

Рубрика: космос | Оставить комментарий

Написание кода для космических аппаратов

 

Нейл: Ваша основная задача в проекте MER заключалась в портировании VxWorks на процессор Rad6000, верно? Работали ли вы также над приложениями для MER? Какие были типичные обращения за поддержкой? Не могли бы Вы привести пример такого обращения из НАСА на этом этапе?

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

Нейл: Чем осложняется написание кода для космических аппаратов?

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

Нейл: Насколько отличается отладка ошибок на земле и в космосе?

Делиман: На земле Вы используете все, что есть под рукой, включая отладочные инструменты (WinView, дампы памяти, отладчики, работающие с исходным текстом и т.д.) Находясь на разных планетах, приходится в основном думать о проблеме и запускать тесты на том, что есть в лаборатории, чтобы посмотреть, удастся ли воспроизвести симптомы.

Нейл: Можете ли Вы привести пример проблемы, с которой пришлось столкнуться в проекте MER? Как Вы исправили проблему — загрузили исправление или целиком новую версию опреационной системы или приложений?

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

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

Нейл: Как различия в космическом аппаратном обеспечении влияют на то, что программы "видят" или делают?

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

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

Делиман: Защитить космический корабль намного проще, чем процессор. Защита процессора может длиться годами и потребует неоднократного тестирования и переделывания, прежде чем удастся получить процессор, который будет одновременно устойчив к радиации и функционален. Это дорогостоящий и длительный процесс. Этим объясняется, почему процессоры, предназначенные для работы в космосе, отстают по своим характеристикам от обычных процессоров. Например, современный "космический" процессор — это чип на основе PPC750, который работает на частоте 130 MHz, тогда как обыкновенный PPC750, работает на частоте более 1 GHz.

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

Нейл: Какие типы программного обеспечения являются ключевыми для операционной системы на космическом корабле?

Делиман: В случае с марсоходами, здесь были программы трех категорий. Первая категория — это программы, разработанные для того, чтобы корабль взлетел с Земли и долетел до Марса; вторая категория — программы, обеспечивающие мягкую посадку на Марсе; и, наконец, третья категория программ была посвящена роли робота-геолога и достижению основных целей проекта: поиску признаков существования воды.

Нейл: Как происходило программирование для космического корабля?

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

Следующая глава: "Жесткие ограничения".

Рубрика: космос | Оставить комментарий

Вы думаете, что ваша операционная система должна быть надежной.

Введение

Майк Делиман был порядком занят в прошлом январе (статья вышла в октябре 2004 года — прим. перев.), когда марсоход Спирит испытывал проблемы с памятью и каналами связи вскоре после посадки на Красной Планете. Он является членом команды в компании Wind River Systems, которая создала операционную систему, работающую в самом сердце марсоходов; и он был одним из тех людей, которые работали круглосуточно, чтобы найти причину и решить проблему, которая таинственным образом приостановила выполнение марсианской миссии.

Делиман работает главным инженером операционных систем в компании Wind River Systems. После окончания Калифорнийского университета в Санта-Круз, со специализацией в области компьютерных и информационных наук, он пошел работать в компанию, работающую с Unix, где и познакомился с VxWorks, операционной системой реального времени производства компании Wind River, адаптированную впоследствии для использования в марсоходах. "Я был очень впечатлен ранней версией VxWorks", — говорит он. "И так сложилось, что буквально через несколько лет после начала моей работы, компания закрыла свои офисы в Сан-Хосе, и я перешел в Wind River". C тех пор он работал над различными космическими проектами вместе с лабораторией реактивных двигателей НАСА.

Беседу с Делиманом о роли программного обеспечения в космосе ведет Джордж Невилл-Нейл, который также знаком с VxWorks. Он разработал модель драйверов устройств для сетевого взаимодействия, которая используется в VxWorks, работал над модификацией TCP/IP стека, позволяющей работать с несколькими экземплярами стека протоколов одновременно, а также портировал открытый (open source) код для сетевых приложений на VxWorks. Он работал в области встраиваемых систем последние восемь лет одновременно в роли интегратора конечных продуктов и конструктора законченных решений в виде встраиваемых операционных систем. Его работа была сфокусирована на сетевых аспектах встраиваемых систем, но он также занимался общими вопросами по широкому кругу аспектов данных систем. Невил-Нейл в настоящее время работает над новым коммерческим DHCP сервером в компании Nominum. Он также проводит семинары и уроки.

Джордж Невилл-Нейл: Как вы оказались вовлечены в работу с НАСА над их космическими проектами?

Майк Делиман: В 1994 году компанию Wind River Systems попросили портировать ее операционную систему на процессоры, защищенные от радиационного излучения, на основе чипа IBM Power, 32-битного предшественника теперешней линейки PowerPC. Чип Power также назывался RS6000; версия с защитой от радиации называлась Rad6000. Мне повезло, что меня попросили помочь с доводкой программного обеспечения Wind River и стать экспертом как по процессору, так и по портированию VxWorks. Все, кто также работал над этим, впоследствии занялись другими вещами, но я остался помогать сотрудникам НАСА использовать наше ПО в других задачах, связанных с космосом: Deep Space 1, SeaWinds, SMEX (Small Explorer Project), Genesis, Stardust, SORCE (Solar Radiation and Climate Experiment), Gravity Probe B и в ряде других зондов и спутников.

Когда начался проект MER (Mars Exploration Rover) меня вызвали и спросили, есть ли человек, который покинул проект Pathfinder и может работать над MER. Таким человеком оказался я.

Нейл: Что означает "защита от радиации" для процессора?

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

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

Нейл: Какова ваша роль в работе с НАСА?

Делиман: В проекте MER с 2001 года по февраль 2004 я был главным инженером операционной системы. Я делал расширения, модификации, исправления ошибок, проводил исследования и портирование — практически все, что касалось участия Wind River в данном проекте.

После этого я покинул Wind River и сейчас работаю в лаборатории реактивных двигателей НАСА.

Нейл: Не могли бы Вы рассказать нам немного о работе в Wind River? Сколько еще людей из Wind River работали над ПО для НАСА и как строились отношения между этими организациями?

Делиман: Я единственный из Wind River, кто работал над ПО для Rad6000. Я консультировался с другими инженерами по специфическим вопросам, но я был единственным инженером, отвечающим за поддержку процессора Rad6000 со стороны Wind River.

Нейл: В чем заключалась Ваша роль во время различных этапов миссии (запуск, полет, посадка, и т.д.)?

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

Следующая глава: "Написание кода для космических аппаратов".

Оригинал "And you think your operating system needs to be reliable."

Рубрика: космос | Оставить комментарий

FPO

Перевод с блога Larry Osterman’s Weblog. Оригинал здесь.

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

Причина, по которой я был удивлен заключалась в том, что я не представлял себе что кто-нибудь до сих пор использует FPO.

Что же такое FPO?

Чтобы ответить на этот вопрос, надо вспомнить предысторию.

Процессор Intel 8088 обладал чрезвычайно ограниченным набором регистров (я не учитываю сегментные регистры), это были:

 AX  [BX]  CX  DX IP
[SI] [DI] [BP] SP FLAGS

При таком ограниченном наборе регистров, у каждого регистра было свое предназначение. AX, BX, CX, и DX были регистами "Общего назначения", SI и DI — "Индексные" регистры, SP — "Stack Pointer" (указатель на стек), BP — "Frame Pointer" (указатель на фрейм стека), IP — "Instruction Pointer" (указатель инструкций) и FLAGS — регистр, доступный только для чтения, который содержал несколько битов, отражающих текущее состояние процессора (к примеру, был ли результат последней арифметической или логической операции равен 0).

Регистры BX, SI, DI и BP были особенными, потому что они могли использоваться как "индексные" регистры. Индексные регистры чрезвычайно важны для компилятора, потому что они используются для доступа к памяти через указатель. Другими словамм, если имеется структура, которая размещается в памяти по смещению 0х1234, вы можете загрузить в индексный регистр значение 0х1234 и обращаться к полям этой структуры относительно этого адреса. Например, команды:

MOV BX, [Structure]
MOV AX, [BX]+4

загрузят в регистр BX значение, содержащееся в указателе Structure, а затем поместят в регистр AX значение слова, расположенного в по адресу Structure + 4.

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

Когдя появился 386-й процессор, в нем регистры были расширены до 32-х бит и все 8 регистров могли использоваться в качестве индексных.

[EAX] [EBX] [ECX] [EDX] EIP
[ESI] [EDI] [EBP] [ESP] FLAGS

Это было здорово, теперь вместо 4-х регистров в качестве индекстных, компилятор мог использовать 8.

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

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

MyFunction:
  PUSH    EBP
  MOV     EBP, ESP
  SUB      ESP, <LocalVariableStorage>
  MOV     EAX, [EBP+8]
  :
  :
  MOV     ESP, EBP
  POP      EBP
  RETD

для доступа к первому параметру на стеке (EBP+0 — это старое значение EBP, EBP+4 — это адрес возврата) можно сделать следующее:

MyFunction:
  SUB     SP, <LocalVariableStorage>
  MOV     EAX, [ESP+4+<LocalVariableStorage>]
  :
  :
  ADD     SP, <LocalVariableStorage>
  RETD

Это работает замечательно — в одночасье стало возможно использовать регистр EBP как и остальные регистры общего назначения! Парни из команды компилятора назвали эту оптимизацию "Исключение указателя на фрейм" ("Frame Pointer Omission"), а нам она известна по аббревиатуре FPO.

Но есть одна маленькая проблема, связанная с FPO.

Если посмотреть на вариант функции MyFunction без FPO, то можно увидеть, что первые две инструкции — это PUSH EBP; MOV EBP, ESP. Они обладали интересным и чрезвычайно полезным сторонним эффектом. Фактически, они создавали односвязный список, который связывал фреймы всей цепочки вызова вплоть до данной функции. При помощи EBP можно восстановить весь стек вызовов. Это было невероятно полезно для отладчиков — можно было восстанавливать стеки вызовов даже если не было отладночной информации для всех отлаживаемых модулей. К сожалению, при использовании FPO, этот список теряется — информация просто нигде не сохраняется.

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

FPO использовалась для всех модулей в Windows в версии NT 3.51, но была отключена в Vista, поскольку в ней не было необходимости — компьютеры стали настолько быстрее по сравнению с 1995 годом, что то небольшое увеличение производительности, которое давало FPO, не стоило тех проблем, которые она создавала при отладке и анализе.

Рубрика: оптимизация | 1 комментарий

Опасайтесь неявных преобразований в С++

Перевод с блога The Old New Thing. Оригинал здесь.

Темой для сегодняшний разговор послужил вопрос клиента:

"Я пытаюсь устранить ошибку, связанную с переполненим стека. Чтобы уменьшить размер стекового фрейма я удалил все локальные переменные, какие только мог, но все равно фрейм остается слишком большим и я не могу понять, где выделяется эта память. Что еще находится в стеке кроме локальных переменных, параметров, сохраненных регистров, и адреса возврата? Да, есть еще данные для структурной обработки исключений (SEH), но они обычно не занимают так много памяти и поэтому не могут быть причиной такого таинственного потребления стека…"

Я предполагаю, что здесь имеет место неявное создание множетсва С++ объектов большого размера. Посмотрим на следующий фрагмент программы:

class BigBuffer
{
public:
    BigBuffer(int initialValue)
    { memset(buffer, initialValue, sizeof(buffer)); }
private:
    char buffer[65536];
};

extern void Foo(const BigBuffer& o);

void oops()
{
    Foo(3);
}

"Разве это вообще скомпилируется? Функция Foo ожидает BigBuffer, а не int!" Да, это скомпилируется.

Это произойдет потому что компилятор использует клнструктор класса BigBuffer как конвертер. Другими словами, компилятор добавлет вот такую временную переменную:

void oops()
{
    BigBuffer temp(3);
    Foo(temp);
}

Он это делает, потому что конструктор, который принимает ровно один параметр может использоваться двояко:
как обычный конструктор (что мы видим в случае с BigBuffer temp(3) ) или для того, чтобы обеспечить
неявное преобразование типа аргумента в конструируемый тип. В этом случае конструктор BigBuffer(int) используется для преобразования типа int в тип BigBuffer.

Чтобы этого избежать следует использовать ключевое слово explicit.

class BigBuffer
{
public:
    explicit BigBuffer(int initialValue)
    { memset(buffer, initialValue, sizeof(buffer)); }
private:
    char buffer[65536];
};

Теперь, вызов Foo(3) приведет к ошибке компиляции:

sample.cpp: error C2664: ‘Foo’ : cannot convert parameter 1 from
‘int’ to ‘const BigBuffer &’
Reason: cannot convert from ‘int’ to ‘const BigBuffer’
Constructor for class ‘BigBuffer’ is declared ‘explicit’

Рубрика: Uncategorized | Оставить комментарий