2010-04-07 3 views
0

Предположим, у меня есть модель домена, которую я пытаюсь сделать совместимой с многопоточным. Домен прототипа - это игровой домен, состоящий из объектов Space, SpaceObject и Location. В SpaceObject есть метод Move, а Asteroid и Ship расширяют этот объект со специфическими свойствами объекта (у корабля есть имя, а у астероида есть цвет)C# Многопоточный дизайн домена

Предположим, я хочу, чтобы метод Move для каждого объекта выполнялся в отдельная нить. Это было бы глупо, потому что с 10000 объектами у меня было бы 10000 потоков. Каким будет лучший способ разделить рабочую нагрузку между ядрами/потоками?

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

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

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

Кто-нибудь знает, что делать здесь?

Спецификация в реакции Deltreme:

Вы Absolutly правильно, и ваш метод будет работать в большинстве случаев. BUT, Потоки должны обновить местоположение космического объекта в классе Space.

Предположим, у меня есть 2 SpaceObjects рядом с eachother, они движутся к eachother. 1 Объект находится в потоке A, другой - в потоке B. Как только я обновляю объекты, потоки должны записывать в Пространство вместе, чтобы писать новые значения в Плитке (отдельная часть Пространства). Этот индивидуальный вызов не может быть выполнен в разных потоках сразу, потому что объект Space будет лопнуть ...

Что может случиться, это столкновение, и я могу написать событие, которое происходит, если они имеют 2 корабля @ 1 плитки. Это не проблема.

Я думаю, что в случае 10000 кораблей CPU будет в основном переключаться между потоками, а не запускать их все. Итак, в интересах производительности, я хочу иметь возможность «все» одновременно

ответ

1

Вы можете использовать System.Threading.ThreadPool или предстоящую параллельную библиотеку задач для автоматического управления количеством потоков в соответствии с количеством доступных ядер.

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

+0

Спасибо, thats helpfull, это означало бы, что я могу оптимизировать 0% в худшем случае и 100% в лучшем случае scneario's. Вы знаете, какой способ улучшить эти шансы? –

0

Предполагаю, вы создаете моментальные снимки: at Situation Каждый объект SpaceObject находится в каком-то местоположении, и после того, как каждый объект SpaceObject переместился в другое местоположение, вы попадаете в ситуацию B.

С 10000 объектами переход между ситуацией А и В составляет 10000 переходов. Move() звучит как довольно быстрый метод, т.е. используя текущее местоположение и направление для создания нового местоположения.

В этом случае вы можете создать 10 потоков (или использовать ThreadPool) и присвоить ему 50 SpaceObjects, для чего он будет вычислять новые местоположения. Если поток выполняется, и все еще есть объекты SpaceObject, которые необходимо переместить, вы назначаете еще 50 этому потоку.

+0

См. Мой обновленный вопрос –

0

Как говорит Хирвокс, ThreadPool - хороший выбор. Я бы избегал думать в терминах потока в SpaceObject, но, скорее, подумал об этом как о большой очереди SpaceObjects, которые все должны обновить свою позицию на интервале, а затем использовать потоки, чтобы выполнить вычисление Move, когда вы удаляете объекты; это хорошо подходит для ThreadPool. Это может быть не настоящая очередь, а может быть отсортированным словарем, но вы получите эту идею.

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

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

Смежные вопросы