Войти
ПрограммированиеФорумОбщее

Применение многопоточности в играх. (Комментарии к статье) (2 стр)

Страницы: 1 2 3 410 Следующая »
#15
1:41, 12 ноя. 2003

aruslan

Внимательнее вчитавшись в статью, я заметил, что наш спор идет ни о чем,  так как в предлагаемом автором примере поток рендера жестко синхронизирован с игровым потоком, причем работают они параллельно только во время переключения буферов. При пересылке данных в GPU работает только ОДИН поток, следовательно, любые блокировки, вызванные переполнениями буферов команд, функцией Lock и др. обязательно отразятся на скорости просчета физики, так как игровой поток ждет окончания пересылки данных GPU. Те же яйца – вид сбоку. Сдается мне, что тестирование производилось при включенной синхронизации  с обратным ходом луча,  благодаря чему и была получена чудесная производительность. Думаю, что если отключить ее (синхр.), то однопоточная схема будет более производительна, чем описанная. Таким образом, если дело только во флипе, можно сделать гораздо проще:

Реализуем, сначала, КЛАССИЧЕСКУЮ однопоточную схему с той, лишь, разницей, что рендер не вызывает САМ переключение буферов. За него это делает отдельный примитивнейший поток, который НИЧЕМ больше не занимается, он нужен только для этого. Никаких вам deadlocks, никакого геморроя с многопоточностью – красота да и только!

P.S.: если я что-то не так понял, поправте.


#16
8:31, 12 ноя. 2003

aruslan
> По этой логике, нам вообще остается всегда только ждать :)
> Представь, что ты начал игру УЖЕ с опережением GPU. Надо готовить почву для следующего кадра.
> Согласись, что абсолютно неважно, насколько ты опережаешь GPU - на кадр или на три.
Ну, более чем спорно. Если мы опережаем GPU, то ждать все равно придется, не увеличивать же отрыв. Не через 2-3, так через 3-4, просто 2-3 - это разумное значение.

> Переполнение push buffer, RenderTarget'ы, блокировка буферов и occlusion culling 100% угробят это начинание.
> Ну, скажем, occlusion culling на GPU вообще все угробит, так что про него пусть YannL пишет.
OQ - вообще непонятная штука. В пределах одного кадра его использовать, видимо, совсем невозможно, а для предыдущего нужно много раз задуматься имеет ли смысл. Если имеет - уже можно бороться за отсутствие синхронизации. Fences и т.д.

> С блокировкой буферов под Xbox можно бороться (до определенной степени) аналогами OpenGL immediate mode (glBegin()....glVertex()...glEnd()).
> На PC блокировка буферов с DISCARD тоже может спасти, хотя YMMV.
Должна спасать, да. Разумеется, кроме случаев когда GPU тормозит. Тогда синхронизация может быть. Но, опять же, далеко не на первом же кадре, а скорее дальше. Опять же, этим до какой-то степени можно управлять, используя разное кол-во буферов и разную стратегию DISCARD/NOOVERWRITE.

> С переполнением буферов команд вообще что-либо сделать трудно.
Тут, действительно, не поспоришь. Хотя в нашем Mileage вроде бы не встречаемся. :)
Или я плохо мерял. Может, есть советы как лучше всего это увидеть без магических Xbox'овых тулзов?

Да, очень интересны комментарии насчет RT. Почему на них может быть CPU stall?

> Если CPU-bound вызван внутренними причинами (что, как правило, редкость), то да, тогда распараллеливание ничего не даст в принципе.
Боюсь, не такая уж. В свете тепершних DIP cost и всего остального.... Мне всегда казалось, что CPU-limited - нормальное поведение для игрушек.

> Обрати внимание, что любой реальный вызов D3D (типа DIP и т.п.) потенциально блокирующий. Причем, надолго.
Я правильно понимаю, что только по соображениям push-buffer'a?

> Если же CPU-bound вызван необходимостью синхронизации с GPU (переполнение push buffer, блокировка ресурсов и т.п.), то здесь мы как раз и можем что-то сделать.
Я правильно понимаю, что те 8 ms на кадр - это именно выгаданные на таких CPU-stall'ах? Можно примерно пояснить какие факторы давали какой вклад?

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

#17
10:36, 12 ноя. 2003

Семен
Ну, более чем спорно. Если мы опережаем GPU, то ждать все равно придется, не увеличивать же отрыв. Не через 2-3, так через 3-4, просто 2-3 - это разумное значение.

Если судить по картинке из статьи, то там вообще нет никакого опережения - рендер и все остальное жестко синхронизированы, никто никого не опережает - сначала расчет, потом рендеринг и т.д.. Да и не понятно, как сделать такое опережение: ведь просчитанные кадры для рендера надо еще как-то сохранять, а это не такая уж тривиальная задачка.

Я правильно понимаю, что те 8 ms на кадр - это именно выгаданные на таких CPU-stall'ах? Можно примерно пояснить какие факторы давали какой вклад?
Если судить по картинке - исключительно Present.

#18
10:40, 12 ноя. 2003

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

Даже если все синхронизировано и во время работы Present никакого доступа к девайсу не осуществляется всеравно нельзя?

#19
10:53, 12 ноя. 2003

prVovik
Ну, картинка довольно символична, да :)
aruslan сам писал, что практические проблемы совсем другие.

> Даже если все синхронизировано и во время работы Present никакого доступа к девайсу не осуществляется всеравно нельзя?
Да. Все вызовы Device'a должны быть из одного треда.

#20
11:30, 12 ноя. 2003

Хм... я наверно не совсем правильно выразился в статье по поводу использования МП в играх. Я лично никого не собирался строить ровными рядами и заставлять использовать в своей игре МП. Не нравится или нет прироста быстродействия (действительно по разному можно спроектировать игру и разные к ней бывают требования) не нужно бросаться на танк с гранатой и пытаться использовать МП. У меня был другой случай, но то у меня.
Далее, пример с распараллеливанием рендера и игры это только пример и ничего более, не говоря о том что саму схему распараллеливания можно организовать по разному. Проявите фантазию, подумайте скажем о распараллеливании загрузки текстур и др. механизмах ускорения программы за счет одновременности операций с различными девайсами. Вариантов применения МП в игре очень много и конкретно рендер тут ни причём.  Ну было бы там описано не распараллеливание рендера, а скажем работа со звуком, текстурами или вводом/выводом, что бы это изменило? Я писал статью для тех у кого возникла необходимость использовать МП в игре и есть трудности с удобностью интерфейса для её использования. Поэтому в статье я предложил вариант такого интерфейса, вдруг это натолкнёт кого-то на новые идеи в этой области, и он поделиться ими с коллегами.
Только не надо утверждать, на основании примера с рендером, что пользы от использования МП в игре абсолютно никакой нет.

#21
11:40, 12 ноя. 2003

Семен
Только что попробовал - в OpenGL все прекрасно работает. Думаю, и в DirectX проблем не должно быть.

#22
11:46, 12 ноя. 2003

LFlip
Разумеется, согласен про подгрузку, звук, сеть и так далее. Вроде как обсуждаем только пример с рендером. Глобально никто с многопоточностью не спорит.

prVovik
Т.е. пробовал отдавать команды на отрисовку во время stall'a CPU из-за синхронизации внутри OGL-ного вызова и все работает?

#23
11:54, 12 ноя. 2003

prVovik
Только что попробовал - в OpenGL все прекрасно работает. Думаю, и в DirectX проблем не должно быть.
А какая видеокарта, какие драйвера и ОС? Если в спецификации нет гарантий что будет работать, есть неплохая вероятность словить BSOD на каком нибудь matrox-е  или др. видяхе. Причем не сразу а в случайной ситуации когда драйвер данные себе как следует попортит в рандомном месте.

#24
12:02, 12 ноя. 2003

LFlip
Мне кажется уже несколько раз это бло высказанно , но попытаюсь сформултровать еще раз.

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

Если же вы планируете работать в реально многопроцессоронй  среде тогда существуют отработанные десятилентиями технологиии, и боюсь данный подход опять же будет не эффективен.

#25
12:09, 12 ноя. 2003

LFlip
>какая видеокарта, какие драйвера и ОС?

Geforce MX440 Detonator 45.23 Win2k


Семен
>Т.е. пробовал отдавать команды на отрисовку во время stall'a CPU из-за синхронизации внутри OGL-ного вызова и все работает?

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

#26
12:14, 12 ноя. 2003

prVovik
Я боюсь, именно в случае вызова OGL-функции во время stall'a другой в соседнем треде все и может сломаться...

#27
12:25, 12 ноя. 2003

Семен
Я повторяю в третий раз: ВСЕ СИНХРОНИЗИРОВАНО!!! То есть примерно вот так вот:

CRITICAL_SECTION cs;
bool flag=false;

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
  while(true)
  {
    EnterCriticalSection(&cs);
    if (flag)
    {
      SwapBuffers(MW_HDC);
      flag=false;
    }
    LeaveCriticalSection(&cs);
    Sleep(0);
  }
}

int main()
{
  InitializeCriticalSection(&cs);
  ...
  CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
  ...

  // On idle
  EnterCriticalSection(&cs);
  if (!flag)
  {
    Render();
    FPS++;
    flag=true;
  }
   LeaveCriticalSection(&cs);
 }

Косяк с ФПС обнаружен...

#28
12:32, 12 ноя. 2003

Ну, простой будет во входе в  критическую секцию, а не в самом SwapBuffers. В чем разница тогда?

Я еще раз позволю себе озвучить свою мысль.
Организация рендера а-ля:
Отдать данные, просчитать след.кадр, Present () в одном треде решает проблему распараллеливания CPU и GPU. Насколько я понял aruslan'a, хочется выгадать не это время, а всяческие другие CPU-stall'ы.

#29
12:44, 12 ноя. 2003

Семен
>Ну, простой будет во входе в критическую секцию, а не в самом SwapBuffers. В чем разница тогда?

Разница в том, что сразу после рендеринга начинается просчет следующего кадра, без захода а SwapBuffers. Как я понял, указываемый прирост скорости в статье был как раз из-за отсутствия простоя в SwapBuffers. Я показал тоже самое, но достигнутое значительно меньшей кровью. Более того, ГОТОВЫЙ проект был переделан примерно за МИНУТУ!


>Насколько я понял aruslan'a, хочется выгадать не это время, а всяческие другие CPU-stall'ы.
Ну это сделать очень сложно. Я уже указыал, что придется как-то сохранять уже просчитанные физикой кадры для рендера, но это не всегда можно сделать.

Страницы: 1 2 3 410 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.