Журнал «Компьютерра» №44 от 29 ноября 2005 года
Шрифт:
Его ассортимент выдержан в духе HP. Такие программы вы найдете фактически на любом коммуникаторе этого производителя[Тем не менее прочитанные обзоры убедили меня в том, что перечень приложений для HP iPAQ hw 6515 может варьироваться]: iPAQ Wireless, GSM/GPRS Settings Manager, HP Profiles, MMS Composer, iPAQ Backup и HP Image Zone. Названия, по-моему, объясняют и предназначение ПО. Прокомментирую лишь категорию беспроводных приложений. Доступ к утилите iPAQ Wireless открыт даже со стартового экрана. Через нее можно вызвать приложение для автоматической настройки параметров GPRS-соединения. У меня почему-то настраивались только параметры для выхода в Интернет; MMS и WAP оставались нетронутыми. Кстати, iPAQ Wireless не подозревает о существовании сети МегаФон, так что ее абонентам уготована ручная работа.
Список
HP iPAQ hw6515 весьма интересен. Нарекания вызывают размер и разрешение экрана, недостает Wi-Fi и ОС Windows Mobile 5.0. Первое непреодолимо, ввиду отсутствия поддержки квадратных дисплеев лучшего разрешения операционной системой Windows Mobile для Pocket PC. Два последних недостатка будут устранены в моделях серии hw67хх, которые должны поступить в продажу в первом квартале 2006 года. Устройства Hewlett-Packard дороги, альтернативы им нет. Впрочем, на фоне стоимости остальных WM-смартфонов цена выглядит обоснованной.
ТЕХНОЛОГИИ: Параллельное программирование
Стояла глухая непроглядная ночь. Редкие огни фонарей освещали безжизненные улицы небольшого городка, отражаясь в раскинувшихся тут и там лужах. Крошечными искрами в их лучах вспыхивали снежинки, медленно падавшие на деревья, улицы и крыши и через минуту исчезавшие без следа. Но люди прижимались к стеклам совсем не для того, чтобы посмотреть на приход зимы. По улицам города, вспарывая тишину, шли покрытые черно-белыми камуфляжными разводами танки.
Но вот лязганье траков по брусчатке внезапно поутихло, а затем и вовсе смолкло, - на очередном перекрестке бронеколонну встретил окоп и наспех выстроенная баррикада. Головной танк, прицеливаясь, повернул башню вправо и слегка опустил ствол. Мгновение безмолвия - и ночь пронзает громкий звук…
…традиционной ошибки приложения Windows, - моя программа, имитирующая сцену сражения, вылетела с очередным малоинформативным сообщением о несвоевременном обращении в оперативную память по адресу 0x85e54f29. «Когда же это, черт возьми, кончится?» - подумал я, со вздохом запуская отладчик…
Как вы уже догадались, эта статья - отнюдь не про войну. Просто мне не хотелось начинать описание технологий параллельного программирования со скучных векторов и систем массового обслуживания, встречающихся в наиболее распространенных параллельных приложениях - всяческих числодробилках типа графических пакетов или кодеров-декодеров и серверах, и я решил остановиться на другом «двигателе прогресса» - на компьютерных играх. С их помощью я попробую объяснить, что такое параллельное программирование, почему оно считается столь трудоемким, почему требует от программиста высокой квалификации и какие инструменты могут облегчить жизнь начинающего (и не только) «параллельного» разработчика. А модельной задачей нам послужит то самое сражение в безымянном городе, с которого начался наш рассказ.
Итак, допустим, что мы делаем стратегическую игрушку по мотивам Великой Отечественной войны. У нас есть игровое поле с разбросанными по нему неподвижными объектами, есть какое-то количество движущихся, умирающих и отстреливающихся объектов (юнитов), есть некий модуль искусственного интеллекта, заставляющий юниты охотиться друг на друга и не ломиться сквозь стену, выполняя приказ игрока, а аккуратно объезжать препятствия. Также у нас есть некий программный код - физический движок, обеспечивающий не только красивый и реалистичный разлет обломков юнитов после прямого попадания, но и более приземленные задачи вроде покачивания танка
Для начала рассмотрим «традиционный» подход к программированию, который в нашем модельном примере выглядит следующим образом. Пишется некоторый кусочек кода (назовем его GameTick), который последовательно перебирает все имеющиеся в игре объекты, «вычисляя» события, происходящие с ними в данный момент времени (Tick, тик). Скажем, один объект - солдат в окопе - «поразмыслил» своим модулем AI, принял решение бросить гранату и бросил ее, сгенерировав новый игровой объект - летящую гранату. Другой объект - брошенный другим солдатом секунду назад «коктейль Молотова» - в результате вычислений физического движка изменил свое положение в пространстве, прошел проверку на соприкосновение с броней танка и прекратил существование. Танк, угодивший под бутылку с зажигательной смесью, перешел из состояния «танк обыкновенный» в состояние «танк горящий». Другой танк повернул башню еще на пять градусов влево. На этом игровые объекты, требующие вычислений, закончились, и сцена с игровыми объектами ушла на обработку к графическому движку, который конвертировал абстрактных солдат, танков и игровое поле во вполне осязаемые полигоны и текстуры, понятные видеокарте. При этом на экране появилась описанная выше картинка, сменившая предшествовавший кадр. А меж тем наша программа опросила клавиатуру и мышь (не решил ли пользователь как-то повлиять на ситуацию?) и перешла на уже известный нам участок кода делать очередной GameTick. Добавим сюда музыкальное сопровождение по вкусу - и игра «заработала»[Разумеется, все не так просто, но в первом приближении можно довольствоваться и этой моделью]. Танки ездят, снаряды летают, геймер отчаянно дает бойцам указания мышкой, в колонках «бумкает» все, что положено… остается лишь записать свежесотворенный шедевр на DVD и топать к издателю.
А теперь представим, что все то же самое мы хотим сделать «параллельно».
Зачем? Ну хотя бы затем, что сегодня это модно. И без технологии HyperThreading и оптимизаций под нее нам уже года три как не жить. На самом деле, конечно, причина грядущего перехода к параллельному программированию в том, что крупнейший производитель процессоров для ПК - корпорация Intel - обещает, что к концу следующего года более 70% продаваемых ею процессоров[А стало быть, как минимум половина всех продаваемых x86-совместимых процессоров] будут двухъядерными, - с чуть меньшей производительностью в пересчете на один-единственный поток исполнения, но зато выполняющие два (или даже четыре) потока одновременно[Подробнее о двухъядерных процессорах см. на offline.computerra.ru/2005/594/39218]. Поэтому если программист сумеет хорошо «раскидать» программу на два параллельных потока (сам процессор делать этого не умеет), то он получит на двухъядерном чипе гораздо большую производительность, чем на аналогичном по стоимости одноядерном. А если не сумеет - то получится как в хорошо знакомом всем россиянам изречении о том, что «хотели как лучше…». Таким образом, налицо и кнут (грозящее снижение производительности, если оставить все «как есть»), и пряник (потенциальный прорыв в скорости) - более чем убедительные аргументы за то, чтобы не отставать от технического прогресса.
Но как это вообще делается? В классическом варианте - полностью вручную. Главный поток программы (который создала при запуске приложения операционная система) формирует (посредством специальных системных вызовов) несколько новых потоков[В случае Unix-систем при этом происходит весьма нетривиальная вещь: при создании первого потока «главный» поток как бы «замораживается» операционной системой, а в операционной системе возникают еще две сущности - новый поток, запущенный по просьбе «главного», и «наследующий» поток, который продолжает исполнение «главного» кода, но не является собственно процессом], приступающих к выполнению программы с того места, которое указывается в числе параметров вызова. Детали реализации в разных ОС отличаются[Существует два основных стандарта: используемый в мире Open Source стандартный интерфейс pthreads (POSIX Threads) и детище Microsoft - так называемая Win32 Threading model], однако принцип совершенно одинаков: одна программа, одни и те же данные, несколько точек исполнения, одновременно перемещающихся по программе. Таким образом, вместо кода типа