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

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

Страницы: 16 7 8 9 10 Следующая »
#90
14:20, 17 ноя. 2003

prVovik
> >В-третьих, [url=http://aruslan.nm.ru/external/kriconf_aosrkmi_final.ppt]здесь[/url] и [url=http://aruslan.nm.ru/external/ctrtbttf.dhtml]вот здесь[/url] (собственно, на gamedev.ru есть обсуждение)
> > можно прочесть некоторые идеи о том, как сделать так, чтобы "копирование" или "реплицирование" стало прозрачным и дешевым.
> Generic programming тут не при чем. Мы же ведь обсуждаем не проблему проектирования ПО вообще, а более "приземленные" вещи, как то:
> реализация конкретного алгоритма. Тут предполагается отсутствие искривлений верхних конечностей девелопера, а такой гипотетический
> супермен и на ассемблере напишет не хуже, чем на С++ with templates...
Так ведь дело не в generic programming (которого, кстати, там в общем-то нет), а в том, что структура рендерных данных на момент
исполнения близка к оптимальной.  В том смысле, что она будет такой, как ты захочешь.
В частности, именно через эти механизмы я преобразовывал объекты в pushbuffers (о чем говорил Boris Batkin) и организовывал
копирование изменившихся данных ( правда, по другому поводу).
Ну да ладно, amen так amen.


Прошло более 1 года
#91
1:00, 5 июня 2005

Добрый день.

Не судите новичка если спрашиваю чтото тривиальное, но вот такая идея, что вы об этом думаете:

Задача: развести обработку визуализации, физику и некоторое др.  в разные потоки с мин. задержками и мин. усложнением кода.

Решение: Возьмём для примера лишь 2 потока: один рендерит, др. проводит перемещения/рассчёты. Есть массив граф. обьектов, по которому бегают главные функции обоих потоков меняя параметры каждого. И тут вот фишка - синхронизация:
В каждом обьекте есть булево свойство, означающее изменяется ли он в данный момент функцией физики. Вот набегает допустим функция физики на обьект который надо сдвинуть: она ставит это свойство в true. Если в этот момент функция рендера набегает на этот обьект, она останавливается и в цикле ждёт пока это свойство уйдёт на false. В это время "физик" его спокойненько переращитывает, ставит false и переходит на след. обьект.
Чтобы рендер не начал рендерить обьект, который в данный момент только начнёт изменяться, тот же механизм в обратном направлении.
И ещё, пожалуй, чтобы уменьшить частоту встречи стоит попробовать пустить оба обработчика в разные стороны. (неуверен плюс это или минус, надо поэкспериментировать)

Я думаю, таким образом можно получить минимальные задержки на синхронизацию, пока не надо юзать функции др. потока.

Что вы об этом думаете?

#92
1:57, 5 июня 2005

плохо... еще подумай
1. >В каждом обьекте есть булево свойство, означающее...
объекты могут возникать новые и умирать старые - грабли
2. >Вот набегает допустим функция физики на обьект который надо сдвинуть: она ставит это свойство в true.
как минимум, InterlockedIncrement...
3. >Если в этот момент функция рендера набегает на этот обьект, она останавливается и в цикле ждёт пока это свойство уйдёт на false.
"активное" ожидание - нехорошо, особенно на 1процессорных машинах... второй серьезный косяк
4. >И ещё, пожалуй, чтобы уменьшить частоту встречи стоит попробовать пустить оба обработчика в разные стороны.
очень сомнительно, что удастся сделать модификацию объектов строго последовательной

#93
12:37, 5 июня 2005

Хм.. ну к 3 ещё можно чтото придумать (в 2 например пропустить обьект и поставить в очередь на рендеринг в конце), 4 - локить не обязательно лишь раз за цикл. 1 - вообще не проблема.

А что с 2? Признаться, не знаю что есть "InterlockedIncrement" (щас смотрю) но рассуждаю так: булево значение лишь 1 байт, как я понимаю к одной и тойже ячейке памяти одновременно обратиться 2 потока не могут, следовательно синхронизации там, вроде, не нужно (по крайней мере на 1 процессоре, многопроцессорные системы меня не интересуют, хотя HT...)

#94
13:09, 5 июня 2005

Basic89
понимаешь, твой "как-бы лок" - активное ожидание это дорогущая операция, особенно на
>1 процессоре, многопроцессорные системы меня не интересуют
если таких локов много - (а их будет много как мы уже выяснили) производительность сильно просядет
при локе с помощью системной функции поток просто снимается с процессора, и не попадает туда, пока не будет выполнено условие разблокировки, при активном ожидании поток весь свой time-slice потратит на дурацкое ожидание (которое бессмысленно, если процессор один)... может быть Sleep(0) в цикле немного выправит картинку, это померить надо; но если конкурентов за объект не 2, а больше, это тоже станет жутко неэфективно (много лишних переключений потоков)

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

>А что с 2? Признаться, не знаю что есть "InterlockedIncrement" (щас смотрю) но рассуждаю так: булево значение лишь 1 байт, как я понимаю к одной и тойже ячейке памяти одновременно обратиться 2 потока не могут, следовательно синхронизации там, вроде, не нужно

if(locked==false) {locked=true; ... /*we have aquired lock*/ }
else {/*lock is not aquired, wait or giveup*/ }
так вот в ассемблере это выглядит так приблизительно
cmp 0, DWORD PTR [locked]    // compare locked with 0
cmov DWORD PTR [locked], 1  // if locked==0, set locked to 1
так вот между этими двумя командами может произойти переключение потоков, и значение locked изменится, прежде чем мы его выставим в true

#95
13:22, 5 июня 2005

Хм..

Спасибо за инфу, буду думать дальше..
Thanks

#96
14:14, 5 июня 2005

Basic89
>Спасибо за инфу, буду думать дальше..
Лучше, имхо, сначала почитать умные книжки...

#97
14:26, 5 июня 2005

2 andrew

Я читаю когда время после школы остаётся. но мне ещё столькому учиться - всё до старости не прочитаешь, а хочется практики.

#98
15:46, 5 июня 2005

Basic89
Практика, имхо, всегда должна быть после теории, а не до :)

#99
16:12, 5 июня 2005

главное, не вместо :)

#100
11:36, 6 июня 2005

Basic89
Гм.. если внимательно почитать мою статью то видно что я как раз не сторонник использования всяких локов, критических секций и т.п. , т.к. в большинстве случаев это сильно усложняет код и делает его не эффективным. Представляю, какое поле для возможных ошибок создаст система, где каждый захудалый объект придётся лочить. Dead lock фактически гарантирован. В своей статье я предлагал не лочить объекты, а передавать между потоками с помощью сообщений, т.е. объектом в какое-то время фактически владеет только один поток, когда он с ним закончил, передаёт другому, ну и т.д. Из-за того, что сообщения между потоками идут постоянно их легко заоптимизировать. Например, в моём случае 96% сообщений передавалось вообще без вызова API функций и только 0.001% вызывало лок в критической секции (возможен, только если несколько потоков шлют сообщения в один).

#101
19:00, 8 июня 2005

Интересно, как в такой системе реализовывалась передача тяжёлых команд между секциями ?
К примеру: команда рендеру рендерить объект. Рендеру надо передать как минимум вертекс буфер и шейдер.
1. добавить в команду умные указатели - выиграть в скорости и проиграть в безопасности
или
2. добавить в команду копирующие указатели - проиграть в скорости но выиграть в надёжности ?

#102
19:45, 8 июня 2005

Nikopol
В моём случае то, что указанно непосредственно в команде копируется, а то на что указывают указатели, не копируется. Программист сам решает, что помещать непосредственно в команду, а что проще передать через указатели.
У меня в движке можно и так и сяк. Есть и копирование и просто через указатели и межпотоковые умные указатели. Короче тут всё зависит от программиста и от того, что ему в данном конкретном случае нужно.
Если сильно упростить всю схему рендера то в случае объектов, рендеру отсылается именно указатель на объект (т.е. на самом деле указатели на всякие  вертекс буферы, шейдеры и т.п.) без копирования. После того как рендер сделал требуемое,  он говорит об этом игре, и игра может снова менять этот объект. Таким образом, надобность в критических секциях отпадает, а если их нет, то нет проблем с dead lock и т.п.

#103
20:10, 8 июня 2005

Nikopol
В команду на рендер объекта у нас передавались аналоги указателей (на объекты рендера).
В твоём смысле - это скорее "умные разделяющие" (vs копирующих) указатели.
Это не проигрыш в безопасности, поскольку игра в любом случае не может выполнить уничтожающие операции.
Очевидным образом, удалять и т.п. объекты, созданные рендером, может только рендер.
Игра максимум арендует у рендера объекты на время.

#104
22:12, 8 июня 2005

LFlip
aruslan
Я не совсем понимаю.
Если, как вы говорите, в подобных командах передаются именно указатели, то что к примеру мешает игровой секции начать менять данные объекта пока секция рендера его рендерит ?
Как эта проблема была у вас решена ?

Страницы: 16 7 8 9 10 Следующая »
ПрограммированиеФорумОбщее

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