несомненно, в будущем эта тенденция только усилится.

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

Не стоит полагать, что каждый пользователь, знакомясь с новой программой, говорит себе: «Пусть эта штуковина работает побыстрее, а не то…» Быстродействие программы чаще оценивается на подсознательном уровне. Работа с быстрой программой, мгновенно реагирующей на все ваши желания, доставляет радость. Хорошее быстродействие вселяет в пользователя уверенность и желание работать дальше. Медленные программы лишь испытывают наше терпение. Каждый, кому приходится работать с ними, мечтают поскорее закончить свои мучения. Пользователи предпочитают, чтобы любая программа (текстовый или графический редактор, игра или любое другое приложение) быстро и адекватно реагировала на их действия.

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

Традиционная оптимизация

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

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

Не стоит просто предполагать, что некоторые части вашей программы работают медленно. Перед началом вскрытия расставьте таймеры в подозрительном фрагменте и воспользуйтесь профайлером Visual C++. Издевательства над невинными функциями не только ведут к напрасным затратам времени, но и повышают вероятность внесения новых ошибок.

Действительно ли C++ медленнее C?

Мы подходим к деликатной теме. Защитники C дружно объединяются для защиты своего любимого языка. Адепты C++ тоже настроены весьма воинственно. К сожалению, преданность такого рода нередко оборачивается неразумным фанатизмом.

Язык C известен своей эффективностью. Именно поэтому он стал первым языком высокого уровня, на котором была написана операционная система (Unix). И все же по скорости C уступает ассемблеру. Он создавался как высокоуровневая альтернатива той чрезмерной детализации, с которой связано программирование на ассемблере.

C++ был создан для того, чтобы обогатить существующий язык C конкретными функциональными возможностями и при этом воспользоваться преимуществами его скорости. Добавлений было несколько, но основным усовершенствованием стало появление объектов, или классов. Более того, первоначально C++ назывался C with classes.

Классы были включены в C++ для поддержки таких объектно-ориентированных принципов, как наследование и полиморфизм. Эти возможности уже присутствовали в других языках (например, в Smalltalk), но C++ был задуман как высокопроизводительный объектно-ориентированный язык. Smalltalk при всей своей мощности работает медленно.

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

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

С другой стороны, C++ не должен лишать вас здравого смысла. Не стоит пользоваться классами только ради удовольствия. Если ваша программа выиграет от того, что некоторая функциональность будет инкапсулирована внутри объекта, — пожалуйста, но превращать в объекты все, что попадается под руку, — скорее всего, перебор.

Программы в этой книге написаны на C++. Обратите внимание на умеренное использование классов. Например, вполне логично использовать класс для представления окна, потому что в MFC входит заранее написанный и протестированный оконный класс. Тем не менее способ применения этого класса более характерен для «просто C».

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

Не бойтесь плавающей точки

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

Аппаратная часть быстрее программной

Если вы уже видели хорошее приложение DirectDraw за работой, то уже знаете это. Приложение, которое работает в режиме 640×480×16 и при этом обеспечивает вывод 60 кадров в секунду, было бы невозможно написать без аппаратного ускорения. Так как DirectDraw автоматически использует все возможности для аппаратного ускорения, вам даже не придется беспокоиться на этот счет.

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

Нехватка видеопамяти

Нехватка видеопамяти становится очевидной после написания первого приложения DirectDraw. На большинстве новых видеокарт установлено 4 Мбайт памяти, но многие карты имеют лишь 2 Мбайт. Это прискорбно, потому что при использовании режимов High и True Color даже 4 Мбайт оказывается не так уж много.

С увеличением разрешения проблема становится еще острее. Например, режим 800×600×24 использует почти 2 Мбайт видеопамяти даже без вторичного буфера. В зависимости от объема установленной памяти можно рекомендовать использование различных видеорежимов, обеспечивающих хорошее быстродействие.

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

Когда свободная видеопамять кончается, поверхности создаются в системной памяти. Хотя системная память и обладает некоторыми преимуществами по сравнению с видеопамятью, быстродействие не относится к их числу. Некоторые видеокарты поддерживают передачу данных из системной памяти через DMA (Direct Memory Access, прямой доступ к памяти), но это временная мера, потому что в ближайшем будущем будет реализована спецификация шины AGP (Accelerated Graphics Port, ускоренный графический порт). AGP позволит видеокарте обращаться к системной памяти с минимальными потерями или без потерь производительности. Более того, AGP-видеокарта может вообще обходиться без видеопамяти и работать исключительно с системной памятью.

Спецификация AGP проектировалась в первую очередь для 3D-приложений, но поскольку библиотека Direct3D построена на базе DirectDraw (и использует DirectDraw для внутреннего распределения памяти), от новых возможностей AGP выигрывает и DirectDraw. К сожалению, для выхода новых аппаратных спецификаций на массовый рынок требуется немало времени. К тому же нет никаких гарантий, что AGP победит — какой-нибудь конструктивный просчет или отсутствие поддержки со стороны производителей может подорвать ее успех.

FPS — еще не все

В наши дни часто приходится слышать о частоте вывода кадров, или FPS (Frames Per Second, количество кадров в секунду). Этот показатель стал мерой для сравнения графических Windows-приложений. Конечно, DirectDraw позволяет создавать приложения с высоким FPS, однако не стоит переоценивать важность этой характеристики.

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

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

Полезные хлопоты с палитрами

Не так давно в высокопроизводительных графических приложениях можно было сколько-нибудь приемлемо работать, лишь используя 8-битные режимы. Так как 8-битные режимы являются палитровыми, палитры были неотъемлемой частью жизни; программист был вынужден либо пользоваться ими, либо отказаться от попыток создания высокопроизводительных графических приложений.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату