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

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

Страницы: 15 6 7 8 9 10 Следующая »
#120
18:36, 2 фев. 2006

Извиняюсь заглупый вопрос, что такое пул?


#121
18:40, 2 фев. 2006

я покопался на google, вообщем про pool понятно.
Тем лучше, можно и так, главное принцип.

Прошло более 1 года
#122
13:44, 18 дек. 2007

Коллеги, с интересом прочитал все обсуждение(впрочем, не первый раз уже :)). Всем спасибо. Особая благодарность LFlip и aruslan. Думаю, всвязи с массовым переходом на многоядерные процы имеет смысл поднять ветку, так как вопрос обретает качественно иные перспективы.

2 LFlip(если Вы еще читаете данный форум):
По результатам своего небольшого опыта разработки МП приложений и чтения статей, у меня сложилось впечатление, что вопрос хорошей параллельности, по сути - вопрос независимости данных. Поэтому хорошо параллелятся потоки развязанные по данным, источники данных (Data(Event) Sources) и отсылка данных во внешние системы (Data(Event) Sinks). В остальных случаях не избежать либо копирования данных с последующей синхронизацией, либо тупого Lock на изменяемый набор данных. Нет ли у Вас неких общих подходов, своеобразных Best practices, для выявления нужных механизмов в зависимости от типа (размера, частоты изменения) данных? Можете поделиться? Может быть, статейку напишете?

#123
13:21, 19 дек. 2007

Полагаю, что если бы существовали некие простые и универсальные методы распараллеливания, основанные на зависимости от типа (размера, частоты изменения) данных, то по логике эти методы нужно применять в процессорах, компиляторах и ОС. Проблема качественного распараллеливания в том и состоит, что её сложно эффективно решить, используя методы, основанные на анализе работы программы с данными. Для эффективного распараллеливания необходим анализ логики поведения программы и её внутренней организации. Как часто и в какие области памяти она при этом обращается не столь важно, т.к. это скорее уровень программирования не на C++ а на ASM-е. Такое распараллеливание вполне по силам ЦПУ, ОС, компилятору. Поэтому, на мой взгляд, в программе, прежде всего, необходимо распараллеливать именно те процессы, о которых более низкие уровни не имеют ни малейшего понятия. Т.е. в первую очередь необходимо распараллеливание логических процессов протекающих в программе (не данных). Что касается критериев распараллеливания, то несомненно, что чем меньше логическая зависимость (не только через данные, а например и по ожиданию неких событий и т.п.) между тем или иным протекающим в программе процессом, тем очевидней, что его надо выделить в отдельный исполняемый поток.
Универсального метода, используя который, программист, глядя на данные профайлера и карту распределения памяти, может написать программу с хорошей параллельностью, у меня, к сожалению нет.

#124
14:06, 19 дек. 2007

Ок. Большое спасибо, LFlip.

#125
22:25, 24 дек. 2007

Алексей (LFlip) - вы с Русланом говорили о версиях 3,4 и 5 MP движка (если я правильно понял). Не мог бы ты описать, в каких направлениях пошли изменения, через что прошли, с чем столкнулись, на чем остановились (20 лет спустя)...

Спасибо заранее.

#126
13:17, 25 дек. 2007

Особо активно я этим движком в последние годы не занимался. Движок работает, проблем нет, зачем в него лезть. Так по мелочи что-то добавить.

Хотя кое-что было сделано. Направлений было несколько:
1. Оптимизация кода движка. В основном цикла обработки сообщений потока, оптимизация самой очереди сообщений, ускорение вызовов обработчиков команд за счёт жёсткой связанности новых специализированных элементов для обмена (T_LINK).
ТЛинки | Применение многопоточности в играх. (Комментарии к статье)
2. Расширение функциональности. Т.е. перенос внутрь движка кода связанного с различными асинхронными действиями (например, загрузка файлов, таймеры, события, сокеты .... ).
3. Улучшение внешнего интерфейса. Чем короче и понятней описание и принцип функционирования той или иной функции движка, тем оно разумеется лучше. Плюс попытки написать Help.chm для этого дела. :)
4. Добавление новых оригинальных возможностей (например, работа с fiber-ами см. пост 115).
5. Выделение кода движка в отдельную lib/dll. Это в основном только мне пригодилось, т.к. в этом случае не требуется перетаскивать гигантское кол-во ненужного кода из движка игры в маленькую программу, ради реализации в этой проге МП.

А вообще в двух словах не объяснишь, слишком обширная тема.

#127
19:32, 25 дек. 2007

Все это очень похоже на попытку приблизиться к Хоаровскому CSP:
http://en.wikipedia.org/wiki/Communicating_sequential_processes
(наверное ты в курсе)

Message loop - это то, где рылись секции в поисках своего сообщения?

Правильно ли я понимаю, что T_LINK - это явный channel из CSP?
В академических целях для сравнения можно глянуть сирую реализацию здесь:
http://www.cs.kent.ac.uk/projects/ofa/c++csp/

#128
20:38, 25 дек. 2007

Я в большей степени практик чем теоретик. :) Мне что попроще, поприземлённей так сказать. В чём то похоже, в чём то нет. Мне важна сама реализация на конкретном языке (С++) и её быстродействие. А так то конечно, можно сделать и так и сяк. Я делал по разному. Например у Nikopol реализация получилась пожалуй даже ближе к CSP чем у меня.

Message loop -  верно цикл обработки очереди сообщений (не только для секций).

T_LINK - это секция с жёстким интерфейсом, благодаря чему в процессе работы программы, при обменах командами между ними, отсутствует надобность в процессе поиска, функций обработчиков команд. Т.е. T_LINK так сказать знают друг-друга в лицо, поэтому, отсылая команду уже в курсе какая функция(и экземпляр объекта) будет её обрабатывать. Ну, ещё всякая ерунда по мелочи. Короче это именно оптимизация (т.е не п.2 и не п.4).

#129
13:18, 27 дек. 2007

Большое спасибо, LFlip.

#130
10:55, 6 фев. 2008

LFlip, насколько я понял, синхронизация в Вашем варианте подразумевается  в коде выделения памяти для команды(Insert)?
(Если рассматривается вариант возможности получения потоком сообщений из нескольких потоков.)

#131
13:33, 6 фев. 2008

svn
Ну, выделение памяти это слишком громко сказано. Правильней сказать, перемещение указателя в циклическом буфере команд и копирование туда самой команды.
Если пишущий поток один, то для реализации достаточно использовать не блокирующие и быстро выполняемые функции типа Interlocked...(вот и вся синхронизация). Если пишущих потоков несколько, то оптимально использовать ещё и критическую секцию на вставку команды в принимающий буфер, т.к. вероятность зацепления потоков  в ней очень низкая (слишком маленькое время на работу с указателем), в связи, с чем критическая секция выродиться в тот же Interlocked (не требует переключения в режим ядра).
Если общее кол-во потоков мало то можно избежать и самой критической секции, для этого сделать каждой паре потоков по своему буферу команд. Естественно, что кол-во таких буферов быстро растёт при увеличении кол-ва потоков (N^2). Попробовав данную схему я от неё отказался, т.к. слишком сильные затраты на память а прироста быстродействия фактически нет.
Также необходимо предусмотреть механизм для пробуждения потока(SetEvent), которому отсылается команда, в том случае если ему нечем было заняться, и он заснул (внутри WaitFor...). Определять необходимость вызова SetEvent, можно например, по результатам, которые вернул Interlocked (при вставке команды), т.е. если команда в буфере оказалась первой то надо будить, если нет, то либо поток не спит, либо его разбудил тот, кто добавил первую команду. В результате когда потоки не спят а постоянно обмениваются командами SetEvent не вызывается и переключения в нулевой режим ядра не происходит, т.е. всё работает быстро.

Итого, сделав замеры на работающем движке в игре, я получил следующие результаты:
96% команд отослались без вызовов системных функций (не считая Interlocked, которые являются простенькими обёртками из пары asm команд).
4% потребовался вызов SetEvent (поток получатель успел заснуть)
0.001% блокировка внутри критической секции (одновременный вход из двух потоков)
Логично, что в случае некой другой игры (или вообще не игры) результаты могут оказаться сильно другими.

#132
4:27, 13 фев. 2008

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

#133
10:26, 13 фев. 2008

svn
Тут можно придумать множество замечательных структур данных с нужными свойствами, и без опасности переполнения.

Навскидку хотябы такая структура:
коллекция блоков памяти с возможностью реюза и роста.

#134
11:15, 13 фев. 2008

Nikopol
Это 100% приведет к критическим секциям.

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

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