Высокая загрузка ЦП с XNA - PullRequest
8 голосов
/ 18 декабря 2011

Я только сегодня заметил, что когда я компилирую и запускаю новую игру XNA 4.0, один из потоков процессора работает на 100%, а частота кадров падает до 54 FPS.

Странно то, что иногда этоработает со скоростью 60 FPS, но затем просто падает до 54 FPS.

Я не замечал такого поведения раньше, поэтому не знаю, нормально ли это.Я удалил свой антивирус и переустановил XNA Game Studio, XNA Redistributable и .NET Framework 4.

Если установить для IsFixedTimeStep значение false, игра будет работать со скоростью 60 FPS, а загрузка ЦП будет минимальной (1-2%).но насколько я знаю, это требует, чтобы я делал расчеты скорости с использованием ElapsedGameTime, но я не знаю, как это сделать, так как я довольно новичок в XNA.Но некоторые говорят, что установка его в false уменьшает отрывистую анимацию.

Я уже проверил эту ветку форума , но никто не нашел хорошего решения.

Кто-нибудь сталкивался с этимпроблема?

РЕДАКТИРОВАТЬ: Я провел еще несколько исследований и внедрил счетчик FPS (до сих пор я измерял его с помощью Fraps), и мой счетчик показывает, что игра работает на скорости 60 FPS (сIsFixedTimeStep = true), так что это решает проблему FPS, но высокая загрузка ЦП остается.Возможно ли, что это случается со всеми?

Ответы [ 2 ]

19 голосов
/ 18 декабря 2011

Согласно этому обсуждению на форуме XBox Live Indie Games , по-видимому, на некоторых процессорах (и ОС) XNA занимает 100% процессорного времени на одном ядре, когда значение по умолчанию Game.IsFixedTimeStep используется .

A общее решение (которое также сработало для меня) - добавить в ваш конструктор Game следующее:

IsFixedTimeStep = false;

Что это значит?

Свойство Game.IsFixedTimeStep, когда true, гарантирует, что ваш кадр (Update(), * 1024)*, ...) вызывается с фиксированным интервалом , указанным в Game.TargetElapsedTime.По умолчанию это 60 вызовов в секунду .

Когда Game.IsFixedTimeStep = false, вызовы следующего кадра будут происходить после завершения предыдущего.Это показано на графике времени ниже:

enter image description here


Как это изменение повлияет на мой код?

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

Предположим, у вас есть

Vector3 velocity;
Vector3 position;

для какого-то объекта, и вы обновляете позицию с помощью

position += velocity;

По умолчанию это будет означать, что скорость вашего объекта составляет 60 * velocity.Length() единиц в секунду.Вы добавляете скорость 60 раз в секунду.

Когда вы переводите это предложение в код, вы получаете простую модификацию :

position += velocity * 60 * gameTime.ElapsedGameTime.TotalSeconds;

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

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

0 голосов
/ 11 сентября 2012

Высокая загрузка ЦП (100% на одно ядро) - без проблем для игр. Другими словами, это ожидается. То, как вы используете процессор при написании игры, требует от вас этого.

Откройте кодовую среду и напишите простую программу

void main(){
    while(1) puts( "aaah" ) ;
}

Откройте монитор процессора и убедитесь, что используется 100% одного ядра.

Теперь ваша игра делает это:

void main(){
    while(1){
        update() ;
        draw() ;

        while( getTimeElapsedThisFrame() < 1.0/60.0 ) ; // busy wait, until 16ms have passed
    }
}

Таким образом, в основном вы звоните update() и draw(), и это занимает большую часть 16 мс, необходимых для вычисления кадра (что вы будете занимать большую часть, когда в вашей игре много вещи в нем).

Теперь, поскольку разрешение сна O / S не является точным (если вы позвоните sleep( 1ms ), оно может на самом деле поспать 20 мс до того, как ваше приложение снова проснется), происходит следующее: игры никогда не вызывают системную функцию O / S Sleep. Функция Sleep приведет к тому, что ваша игра будет «проспать», и игра будет выглядеть медленной и медленной.

Хорошее использование процессора не стоит, если приложение не отвечает на запросы. Таким образом, стандарт заключается в том, чтобы «ждать ожидания» и сокращать время при загрузке процессора.

...