Подтвердить что ты не робот

Почему не большие программы (например, игры) не используют множество разных потоков?

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

Почему в играх не много потоков? Например, отдельные темы для физики, звука, графики, AI и т.д.

4b9b3361

Ответ 1

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

Это становится особенно популярным на консолях. PS3 основан на архитектуре ячеек, поэтому вам нужно использовать параллельную обработку, чтобы получить лучшую производительность из системы. Xbox 360 может эмулировать настройку задачи/задания, которая была разработана для PS3, поскольку она имеет несколько ядер. Вероятно, вы найдете в большинстве игр, что большая часть системного дизайна разделяется между 360, PS3 и кодовыми базами ПК, поэтому ПК, скорее всего, использует такую ​​же тактику.

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

  • Во-первых, многие игры с открытым исходным кодом несколько лет. Особенно с этим поколением консолей параллельное программирование становится популярным и даже необходимым, как упоминалось выше.
  • Во-вторых, очень мало проектов с открытым исходным кодом, похоже, обеспокоены получением максимально возможной производительности. Поскольку Джон Кармак указал на проект Utah GLX, высоко оптимизированный код часто сложнее поддерживать, чем неоптимизированный код, поэтому последний обычно предпочтителен в контекстах с открытым исходным кодом.
  • В-третьих, я бы не взял небольшое количество потоков, созданных игрой, чтобы означать, что он не использует параллельные задания.

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Что касается игр, я не программист игр, но мое понимание ситуации таково: 3D-игры создают программную модель игрового мира; игроков, врагов, предметов, местности и т.д. Этот игровой мир обновляется в виде дискретных шагов, исходя из количества времени, прошедшего со времени предыдущего обновления. Итак, если 1 мс прошло с момента последнего раунда игрового цикла, положение объекта обновляется, используя его скорость и прошедшее время, чтобы определить дельту (очевидно, физика немного сложнее, чем это, но вы получаете идея). Другие факторы, такие как AI и клавиши ввода, также могут способствовать обновлению. Когда все будет закончено, обновленный игровой мир будет отображаться как новый кадр, и процесс начнется снова. Этот процесс обычно происходит много раз в секунду.

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

Величины меняются при использовании многоядерной системы. Теперь задачи могут выполняться по-настоящему одновременно, и действительно может быть полезно использовать потоки для обработки различных частей обновлений игрового мира, пока мы можем синхронизировать результаты для рендеринга согласованных кадров. Поэтому мы ожидаем, что с появлением многоядерных систем разработчики игровых движков будут работать над этим. И так получается, они есть. Valve, создатели Half Life, недавно представили многопроцессорную поддержку в своем Source Engine, и я думаю, что многие другие разработчики двигателей следуют примеру.

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

Ответ 5

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

x86 был очень доволен игровым программистам, поскольку нам не приходилось думать о последствиях менее прощающих аппаратных платформ.

Ответ 6

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

Теперь, когда многоядерные процессоры вышли на время, а основные игровые консоли имеют несколько ядер, это всего лишь вопрос времени, пока два ядра не появятся в списке минимальных системных требований для игр для ПК.

Здесь ссылка на интервью с Орион Гранатир от Intel, где он говорит о том, чтобы заставить разработчиков игр использовать многопоточность.

Ответ 7

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

Лично я думаю, что нам понадобится сдвиг парадигмы и новые инструменты.

Ответ 8

Нити мертвы, малыш.

Реально, в разработке игр потоки не масштабируются, не выгружая очень специализированные задачи, такие как создание сетей и загрузка. Системы работы, похоже, являются единственным способом продвижения вперед, поскольку 8 систем ЦП становятся все более обыденными даже на ПК. И вы можете в значительной степени гарантировать, что предстоящие супер-многоядерные системы, такие как Intel Larrabee, будут основаны на работе.

Это было несколько болезненное воплощение в проектах Playstation3 и XBOX360, и теперь кажется, что даже Apple вскочила на борт со своим "революционным" Grand Central Dispatch в Snow Leopard.

Темы имеют свое место, но наивное обещание "поместить все в поток, и все будет работать быстрее" просто не работает на практике.

Ответ 9

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

Ответ 10

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

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