четверг, июля 26, 2007

Программное обеспечение и параллельная революция (Часть 5)

Херб Саттер (Herb Sutter) и Джэймс Лэрус (James Larus), Microsoft.

Часть 5. Потребности в инструментах

Что нам надо среди инструментов

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

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

Инструменты для систематического выявления дефектов необычайно важны в этом мире. Такие инструменты используют статический анализ кода программы для систематического выявления всех возможных путей исполнения, таким образом, они способны обнаружить ошибки, которые невозможно воспроизвести. Хотя подобные методики, такие как верификация модели, с большим успехом используются для обнаружения дефектов в аппаратном обеспечении, которому тоже присущ параллелизм, с программным обеспечением все сложнее. Количество возможных состояний любой программы гораздо больше, чем это характерно для большинства hardware, поэтому необходимо гораздо больше работы для систематического анализа состояний программы. В обоих случаях, модульность и абстракция являются ключевыми моментами для упрощения анализа. Если при тестировании модели процессора мы можем выделить АЛУ (арифметико-логическое устройство) и анализировать его отдельно от набора регистров, то задача анализа существенно упрощается.

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

Инструменты для выявления дефектов в параллельном ПО являют собой область для активных исследований. Одна из перспективных методик от Microsoft Research под названием KISS (Keep it Strictly Sequential) (4) преобразует многопоточную программу в последовательную, которая включает все возможные чередования оригинальных потоков. Преобразованная таким образом программа может быть проанализирована большим количеством существующих инструментов для анализа последовательных программ.

Даже продвинутые программисты все же нуждаются в хороших отладчиках, которые позволили бы им разобраться в запутанных и сложных для воспроизведения взаимодействиях в их параллельных программах. Существует две основные методики для сбора этой информации. Первая, это улучшение возможностей логирования, включая отслеживание сообщений передаваемых процессам и того, какие потоки обращаются к каким данным, что позволило бы разработчику отследить и понять порядок исполнения в своей программе. Разработчики также нуждаются в возможностях отслеживать причинно следственные связи между потоками (например, какие сообщения направлены одному активному объекту, когда обработаны, как связаны с другими сообщениями к другим активным объектам?), перезаписи и изменения порядка сообщений в очередях, пошагового исполнения асинхронных вызовов включая обратные вызовы (callbackы), и прочие возможности исследования параллельного исполнения своих программ. Другой подход, это обратное исполнение кода, которое позволяет программисту записать ход исполнения программы и затем повторно «проиграть» этот код. Replay debugging не является новой идеей, но ее реализации мешали высокая сложность и ресурсоемкость. Появившиеся недавно мониторы виртуальных машин (5) (virtual machine monitors) способны снизить оба фактора. В параллельном мире эта методика, вероятно, окажется востребованной.

Нагрузочная отладка и оптимизация также потребуют новых инструментов в параллельном мире. Параллелизм порождает новые узкие места, такие как конфликты блокировок, издержки на поддержание когерентности кэша (проблема false sharing, например. Примечание переводчика), “lock convoys”, которые трудно отследить при помощи обычных профилировщиков. Новые инструменты, более приспособленные к конкретным компьютерным архитектурам и к особенностям параллельных программ, будут более эффективны при обнаружении подобных проблем.

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

Ключ в параллелизме

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

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

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

Ссылки

1. Sutter, H. 2005. The free lunch is over: a fundamental turn toward concurrency in software. Dr. Dobb’s Journal 30 (3); http://www.gotw.ca/publications/concurrency-ddj.htm.
2. Ramalingam, G. 2000. Context-sensitive synchronization-sensitive analysis is undecidable. ACM Transactions on Programming Languages and Systems 22 (2): 416-430.
3. Dean, J., and Ghemawat, S. 2004. MapReduce: simplified data processing on large clusters. Proceedings of the Sixth Symposium on Operating Systems Design and Implementation, San Francisco, CA: 137-150.
4. Qadeer, S., and Wu, D. 2004. KISS: Keep it Simple and Sequential. Proceedings of the ACM SIGPLAN 2004 Conference on Programming Language Design and Implementation, Washington, DC: 1-13.
5. King, S. T., Dunlap, G. W., and Chen, P. M. 2005. Debugging operating systems with time-traveling virtual machines. Proceedings of the 2005 Annual Usenix Technical Conference, Anaheim, CA: 1-15.
6. Chandra, S., Godefroid, P., and Palm, C. 2002. Software model checking in practice: an industrial case study. Proceedings of the 24th International Conference on Software Engineering, Orlando, FL: 431-441.

3 комментария:

Анонимный комментирует...

Erlang нам поможет;)

Sergey Rozovik комментирует...

to npx
Не внимательно читали.
В 4 части авторы функциональным языкам уделили внимание. Не очень то они помогут в этом деле.

Анонимный комментирует...

to Sergey Rozovik
>Не внимательно читали.
Внимательно читал, и сделал вывод, что Sutter с Erlang'ом не знаком.

Кстати, спасибо за перевод.