Семь подводных камней: Wind River в помощь отладчику

№ 10’2012
Десятилетиями в вопросах увеличения производительности ПО разработчики полагались на миниатюризацию, повышение тактовых частот и архитектурные улучшения одноядерных процессоров. Однако многоядерные процессоры предоставляют больше функциональности при меньших габаритах и рассеивают меньшую мощность. Для производителей встраиваемых приложений эти свойства являются весьма значимыми. Выигрыш от применения многоядерных архитектур на фоне традиционных одноядерных решений становится все более ощутимым. По прогнозам компании VDC Research, сделанным в 2010 г., в настоящий момент 61% разработчиков должны были бы использовать в своих проектах многопроцессорные и/или многоядерные архитектуры. Однако повторный опрос, проведенный в 2011 г., позволил компании уточнить эти цифры до 73%.

Очевидно, что дизайн многоядерных приложений в корне отличается от традиционного. Факторов, которые разработчикам приходится учитывать с переходом на многоядерные архитектуры, становится все больше, и хотя в итоге выигрыш высок, существует ряд типовых «ловушек», которых следует опасаться. Часть из них сугубо технические и связаны со сложностями программирования и отладки; прочие можно отнести к охвату требований и рискам, связанным со сроками и бюджетом. Как бы там ни было, согласно исследованиям Embedded Market Forecasters, этих сложностей достаточно, чтобы не удавалось четверть всех проектов многоядерных систем завершить в установленные сроки и удовлетворить функциональные требования как минимум на 50%.

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

Точки останова могут помешать отладке

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

Можно, конечно, использовать интерфейс JTAG, но его реализации отличаются друг от друга, и при переходе на многоядерную архитектуру надо четко понимать, в чем именно состоят различия. Одним из больших преимуществ JTAG является способность полностью остановить процессор, что дает четкую картину его состояния на момент выполнения определенной секции кода (при использовании же традиционных методик отладки после срабатывания точки останова низкоуровневые операции продолжают выполняться). С другой стороны, даже в мире JTAG с переходом на многоядерные архитектуры отладка сильно усложняется — вплоть до использования нескольких JTAG-соединений и отладочных агентов на каждом ядре, что может довести до реального «инструментального кошмара».

JTAG-эмулятор Wind River ICE 2 был изначально разработан с учетом особенностей отладки многоядерных систем, включая поддержку синхронизации точек останова и логической группировки ядер. Допустим, например, что вы разрабатываете сетевое устройство. Необходимо на восьмиядерном процессоре обеспечить работу двух операционных систем (ОС) одновременно — Linux в SMP-режиме на двух ядрах (функции управления) и специализированной сборки ОС реального времени на остальных (плоскость данных). JTAG-решение от Wind River позволяет объединить ядра, занятые обработкой одной ОС, в логическую группу и синхронизировать все отладочные операции в этой группе. Таким образом, ваша система будет представлена в отладочной среде точно так же, как на архитектурной диаграмме, но можно будет в случае необходимости углубиться в детали работы каждого конкретного ядра. Никакие другие отладочные средства не позволяют это делать. При этом Wind River ICE 2 поддерживает отладку до 16 ядер одновременно, так что с ним вы можете собрать весь отладочный макет за один прием.

Системные журналы могут создать путаницу

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

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

Функции Wind River ICE 2 можно расширить, применяя внешний модуль Wind River Trace. Он предоставляет для поддерживаемых процессоров дополнительный буфер трассировки, позволяя отслеживать выполнение кода и решать сложные проблемы, для диагностики которых недостаточно анализа состояния регистров и памяти.

Истинный параллелизм может быть коварен

Совместный доступ к ресурсам в многоядерных архитектурах может приводить к неявным и трудно диагностируемым «гонкам». Возьмем, к примеру, обычный цикл for, в котором два ядра обновляют одну и ту же глобальную переменную таким образом, что цикл никогда не завершается. Изучение исходного текста и пошаговое выполнение кода не покажут ничего необычного, пока вы не примените аппаратные контрольные точки данных (hardware watch points), которые укажут на источник проблемы.

Более удачным подходом к диагностике в многоядерных средах является использование инструментария, который давал бы детальное представление о выполнении кода на каждом ядре. Качественный инструмент системного профилирования при этом внесет минимальные накладные расходы — примерно 1%.

В ряде случаев потребуется абсолютно «бесконтактный» подход. Использование внешнего аппаратного отладчика может дать точную детализацию взаимодействия между аппаратурой и ПО, включая состояние внутренних шин, кэша и счетчиков команд, при этом никак не влияя на поведение системы. Внешний отладчик также позволит записать в динамике и впоследствии проанализировать содержимое счетчиков команд, что выявит точную последовательность команд, выполняемых процессором, — неоценимый инструмент в анализе проблем неоптимального распределения процессов по ядрам (например, когда ОС в SMP-конфигурации неоправданно переносит процесс с одного ядра на другое).

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

В Wind River уделено большое внимание разработке инструментария для визуализации и профилирования поведения многоядерных встраиваемых систем. Такие инструменты, как Wind River System Viewer, позволяют динамически отслеживать состояние примитивов ОС (задач, потоков, семафоров и т. п.) в контексте ядер, на которых выполняется соответствующее ПО. Внешний аппаратный модуль Wind River Trace предоставляет возможность «неинвазивного» анализа низкоуровневых деталей выполнения кода — таких, например, как состояние счетчиков команд.

«Неправильные» инструменты могут парализовать проект

Целостный подход к разработке и отладке очень важен в проектах на базе многоядерных архитектур с точки зрения достижения высокой масштабируемости и производительности. В выборе инструментальной платформы недостаточно полагаться только на требования конкретных задач или компонентов. Необходим всеобъемлющий подход.

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

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

Способность выполнять отладку многоядерных конфигураций на системном уровне является неоценимой для глубинного анализа программных дефектов, проблем с производительностью, а также для определения возможных точек оптимизации. Wind River ICE 2, Wind River Trace и Wind River Workbench On-Chip Debugging в совокупности представляют собой интегрированное отладочное решение, содержащее мощную среду разработки, средства анализа многоядерных систем и инструменты внутрисхемной отладки.

Сложность многоядерных систем может стать причиной краха проекта

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

Многоядерные технологии пока еще довольно молоды, и такие термины, как AMP, SMP, виртуализация и гиперпоточность (hyperthreading), для многих могут быть в новинку. Не все разработчики сразу способны осознать проблемы, зачастую возникающие при попытке выполнить унаследованный код на многоядерном устройстве. По мере того как в работе с многоядерным оборудованием будет задействовано все больше разработчиков, все больше людей будет сталкиваться с проблемами синхронизации доступа к ресурсам, которыми раньше занимался один выделенный специалист, и это способно привести проект к хаосу. Чтобы такого не произошло, необходимо изначально снабдить всю команду подходящим инструментарием.

Ожидайте от вашей кодовой базы существенного разрастания. Код, написанный для одноядерной системы, при переносе на четырехъядерную существенно «распухает», чтобы вписаться в необходимые требования. В результате навигация в исходном коде и управление им становятся громоздкими и неэффективными. Мало того, классические отладчики вынуждают открывать отдельные окна для каждого ядра. А это означает, что, скажем, на 16-ядерной системе для понимания происходящего в системе придется постоянно переключаться между 16 окнами. Поэтому важно, чтобы отладчик позволял и видеть всю систему в целом, и по необходимости углубляться в детали функционирования каждого конкретного ядра.

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

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

Интегрированная среда Wind River Workbench On-Chip Debugging предоставляет множество средств управления исходным кодом, в частности мощные инструменты редактирования, включая эмуляцию vi и Emacs, автозавершение кода, подсказки параметров и подсветку синтаксиса, оптимизирующие цикл «редактирование–компиляция– отладка» и уменьшающие количество ошибок. Редактор при этом тесно интегрирован с системой управления и построения проектов, анализатором кода и отладчиком, позволяя легко переключаться между различными задачами, возникающими по ходу отладки в исходном тексте. Wind River ICE 2, в свою очередь, поддерживает широкий выбор процессоров с различными архитектурами и отладочных плат на их базе. Возможность подключения Wind River ICE 2 через Ethernet позволяет предоставлять доступ к нему всем необходимым сотрудникам, даже территориально удаленным. Все это, в сочетании с технической поддержкой и учебными программами от Wind River, поможет преодолеть барьеры, возникающие при переходе на многоядерные архитектуры.

Увеличение числа ядер может снизить производительность

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

Мало того, согласно закону Амдала (Amdahl’s law), выигрыш в производительности, который можно получить от параллелизации, ограничивается объемом вычислений, которые параллелизации не поддаются. Если программа тратит 10% времени выполнения на непараллелизуемые операции, то, вне зависимости от количества применяемых вычислителей, ее выполнение нельзя ускорить более чем в 10 раз. В реальности даже 5% непараллелизуемых операций достаточно, чтобы свести на нет все преимущества многоядерного подхода.

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

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

Wind River Workbench позволяет воспроизводить и анализировать предварительно записанную информацию о системных событиях в интуитивном графическом представлении System Viewer. С помощью System Viewer можно быстро идентифицировать пиковые нагрузки, сортировать события по частоте и выделять конкретные события или события определенного типа.

Представление Workbench Performance Profiler позволяет анализировать использование вычислительных мощностей различными частями приложения и переходить к анализу наиболее «затратных» областей на уровне исходного текста для более детального рассмотрения и оптимизации. Workbench Code Coverage Analyzer дает анализ покрытия кода в реальном времени и помогает быть уверенным в том, что код, выполняющийся в многоядерной среде, не содержит непроверенных участков. Workbench Data Monitor позволяет отслеживать состояние переменных (в том числе разделяемых), структур данных и адресов памяти в реальном времени. Все эти и многие другие диагностические инструменты дают необходимую детализацию поведения системы, позволяя настроить ее на максимальную производительность.

Просить помощи — нормально

Круглосуточная «горячая линия» технической поддержки стала спасательным кругом для многих проектов по разработке многоядерных устройств. Скажем, некая компания, работающая над проектом на базе SMP-конфигурации Linux, на фазе интеграции внезапно сталкивается с непредсказуемым зависанием системы. Перепробованы всевозможные методики отладки — запись в системные журналы, вывод printf (), ревизия кода. В результате удалось добиться более-менее стабильного воспроизведения проблемы, но ее причина так и осталась неясна. И только после обращения за помощью в техническую поддержку Wind River проблема была быстро локализована. Как выяснилось с помощью JTAG-инструментария Wind River, дефект вообще не относился к коду проекта: дело было в реализации буфера ассоциативной трансляции (Translation Lookaside Buffer, TLB) в ядре Linux, которая была рассчитана на использование на одно-ядерном процессоре, а на многоядерном вызывала блокировку. Этот дефект долгое время существовал вместе с проектом и никак себя не обнаруживал, пока проект не был переведен на многоядерную архитектуру. Благодаря своевременному обращению в техническую поддержку проект был спасен.

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *