Главная » Статьи » Общее

Массовые Многоядерные Процессоры: Край Геймра (Massive Multi-Core Processors: The Gamer’s Edge)
Массовые Многоядерные Процессоры: Край Геймра
Massive Multi-Core Processors: The Gamer’s Edge


Массовае многоядерные процессоры, на подобии предстоящего AMD Phenom ™ четырех ядерные (quad-core) процессоры, представляют будущее для всех пользователей PC …, но прежде всего для геймеров. Эта статья обсуждает факторы, которые разработчики, особенно разработчики игр, должны иметь в виду, используя многоядерный процессор: такие как оптимизация кеша, оптимизация многопоточности, и ускорения за счет 128-битных SSE-инструкций.

Краткий обзор
Алан Зеичик
(Alan Zeichick) 10/04/2007


Ничто не выделяет настольный PC больше чем современные игры. Вы хотите использование центрального процессора? Вы хотите использовать много памяти? Вы получите это. Современные игры PC для Windows® XP и Windows Vista – замечательное развлечение для игроков, но они - также являются серьезными приложениями, комбинируя огромные наборы данных, сложные математические алгоритмы (и с плавающей запятой и целочисленные), анимация 3D персонажей в реальном времени, трассировка луча и рендеринг в высоком разрешении с наложением текстур.

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

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

В течении нескольких прошлых лет, пределом мечтаний для серьезных геймеров была система с двуядерным процессором. Но это скоро изменится, поскольку центр тяжести изменится с появлением четырехядерных процессоров, наподобие ожидаемого с нетерпением AMD Phenom quad-core. Это даст играм hi-end класса в два раза больше аппаратных средств - и во многих случаях, простой апгрейд процессора даст турбо заряд для вашей существующей геймерской платформы.

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

Так, что Вы можете сделать? Если бы Вы думали о требованиях игр, и о характеристиках игровых систем класса hi-end, план с четырьмя шагами был бы:
• Оптимизируйте, чтобы использовать преимущества кэширования, и особенно, при проектировании разделенного-кеша(shared-cache), используемого многоядерными процессорами AMD.
• Проектируйте с учетом масштабирования потоков для систем с несколькими ядрами.
• Где только возможно, используйте возможности работы с векторами 128-битового SSE.

Оптимизируйте под кешь

Спецификации для четырехядерных процессоров AMD внушительны. Они предлагают четырехядерное решение, где каждое ядро имеет собственный кешь L1 и L2. Ядра используют общий кешь L3 и контроллер памяти, который выходит к банку памяти RAM, непосредственно связанной с тем процессором. В то время как большинство разработчиков может игнорировать кешь, если Вы находитесь в игровом бизнесе, понимание специфики ядра 512 КБ-айтных L2 кешей и общего L3 кеша, может помочь Вам контролировать каждый бит производительности непосредственно из приложения.

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

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

Точно так же избегите записи больших объемов данных в память, и последующего их считывания - продолжайте использовать кеша везде, где только возможно. Когда Вы записываете данные (например, на диск), используете инструкции Потокового Хранения(Streaming Store instructions), которые не будут засорять кешь L2.

Также думайте тщательно о ваших структурах данных. Делайте все возможное, чтобы избежать расточительного дополнения в структурах (проверьте элемент struct, используя sizeof ()), так, чтобы Вы не тратили кешь впустую. Иногда двухбайтовое смещение значения или индекса массива могут заменить четырехбайтовый или восьмибайтовый указатель …, и это огромно при максимизировании вашего кеша.

Очевидно, много работы уйдет на то, чтобы проверить каждый struct, операцию памяти, и т.д., и Вы, возможно, должны использовать ваши ресурсы с умом. Используйте инструменты такие как CodeAnalyst от AMD, чтобы отслеживать горячие точки как утечка кеша. Инструмент является бесплатным - каждый разработчик под Windows должен его установить. Вы можете прочитать несколько статей которые я написал об этом: “Cache or Check: CodeAnalyst Addresses Performance Deficits” и “Got Bottlenecks? CodeAnalyst Can Help”.


Проектируйте с учетом масштабирования потоков

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

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

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

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

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

Как достичь параллельной работы с данными? Используйте техники такие как OpenMP, чтобы повысить производительность работы циклов и других итерационных процессов. Используйте пул процессов для сложных алгоритмов. Вы можете узнать больше об этом прочитав вводную статью “Implicit Threading, Explicit Threading: What's Best, How To Choose” Андерсона Беили(Anderson Bailey); также обратите внимание на "OpenMP: Getting Fancy with Implicit Parallelism” и “OpenMP: More than Just Optimizing Loops”.

Используя параллельные потоки данных, воспользуйтесь одним предложением: Сведите блокирование данных к минимуму. Блокирование не масштабируется … потому что, чем больше потоков выполняют работу над одним набором данных, тем больше вероятность того, что один или более потоков будут простаивать в ожидании доступа к данным - или могут возникнуть «мертвые», заблокированные участки. Хуже, что вы можете оказаться в конце гонки, когда данные в одном потоки будут обновляться другим потоком. (Когда Вы имеете дело с кешем, «мертвые блоки и гоночные условия еще более опасны.) Проектируйте ваши алгоритмы тщательно, чтобы избежать потребности блокирования данных, таким образом Вы добьетесь того, что приложение будет и более безопасно и более масштабируемо.
Используйте Векторные Операции, чтобы Получить Выигрыш от 128-битных SSE-инструкций

Если бы я должен был охарактеризовать уникальный аспект современного игростроения, я сказал бы, “Использует много векторов.” Очевидно, матречніе и векторные операции используются во многих алгоритмических приложениях, включая финансовое моделирование, трехмерное автоматизированное проектирование(3D CAD), и другие …, но игры просто переполнены векторными операциями. Как упоминалось выше, такие алгоритмы идеальны для параллельных потоков данных, и в сочетании с аккуратным проектированием, могут быть реализованы с минимальным количеством блокировок данных.

Разработчики, пишущие векторный код получают мощного союзника в лице 128-битных SSE-инструкций, которые представлены в процессорах начиная с AMD Phenom. 128-битные SSE-инструкции могут удвоить векторную пропускную способность SSE, по сравнению с предыдущими процессорами AMD.

Например, рассмотрите ADDPD (Add Packed Double), инструкцию. Предыдущие процессоры AMD преобразуют эту инструкцию SSE в две микрооперации сложения(ADD), каждая из которых проходит через 64-битный сумматор. С использованием 128-битных SSE-инструкций, ADDPD преобразуются в одну микрооперацию сложения(ADD), которая выполняется за один проход через 128-битный сумматор. Для технического краткого обзора, см. “SSE128: AMD's New Floating-Point Enhancements". Если Вы скомбенируете увеличенную эффективность, которую дает 128-битные SSE-инструкции при работе с векторным преобразованиям, и силу параллельной обработки данных в потоках, Вы можете дать вашим играм огромный прирост производительности.

Лучший способ получить выгоду от 128-битных SSE-инструкций – воспользоваться последними векторезированными SSE библиотеками от AMD, такими как AMD Performance Library. Они содержат оптимизированный SSE код, написанного для достижения высокой мультипоточности, и предлагает много рутин для математических операций с массивами и обработки изображений. Некоторые библиотеки сторонних производителей также были оптимизированы под 128-бит:

Bink video library
Granny 3D Toolkit
Havok
Miles Sound System


Разработка Игр – Серьезный кодинг

Геймеры запускают самые сложные, самые ресерсоемкие приложения из тех, которые когда-либо существовали на потребительском рынке. Они возлагают большие надежды, и когда они выкладывают свои деньги для четырехядерный процессор, они собираются получить соответствующий прирост производительности в играх. Мы увидели, какие оптимизации Вы можете сделать, чтобы использовать в своих интересах кэширование, проэктирование масштабируемых потоков для систем с многими ядрами, и ускорить векторные операции с использованием 128-битных SSE-инструкций. Эти три техники должны быть в комплекте инструментов каждого разработчика игр для Windows …, потому что четырехядерные системы собираются занять господствующее место.

Алан Зеичик(Alan Zeichick) – технический консультант и аналитик, сосредоточенный на разработке программного обеспечения и микропроцессорных технологиях. Свяжитесь с ним zeichick@camdenassociates.com, и прочитайте его блог на http://ztrek.blogspot.com.

Перевод: by VileDog
Original - http://developer.amd.com/articles.jsp?id=177&num=1
PS. Прошу сообщать о всех неточностях перевода.
Категория: Общее | Добавил: viledogsoftware (09.10.2007)
Просмотров: 3967 | Рейтинг: 2.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]