Варианты системы передачи сообщений для игры - PullRequest
0 голосов
/ 16 июня 2009

Я работаю над RTS-игрой на C ++, предназначенной для портативного оборудования (Pandora). Для справки: Pandora имеет один процессор ARM с тактовой частотой ~ 600 МГц и работает под управлением Linux. Мы пытаемся установить хорошую систему передачи сообщений (как внутреннюю, так и внешнюю), и для меня это новая территория.

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

sendMessage("model-loader", "load-model", my_model.path, model_id );

В свою очередь, устройство может ожидать какое-то сообщение, содержащее объект модели для конкретного model_id, которое затем может быть передано в графическую систему. Обратите внимание, что эта функция sendMessage ни в коем случае не является окончательной. Это просто отражает мое текущее понимание систем передачи сообщений, что, вероятно, неверно:)

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

Другой вариант - полностью перейти на сетевой уровень. Это имеет некоторые забавные преимущества, такие как получение асинхронной передачи сообщений бесплатно. Кроме того, мы получаем возможность передавать сообщения на другие машины, используя те же вызовы, что и локально. Однако, это решение меня теряет, вероятно, потому, что я не до конца его понимаю :) Нужен ли нам сокет для каждого объекта, который будет отправлять / получать сообщения? Если так, это кажется чрезмерным. В данной игре будут тысячи объектов. Я боюсь, что для такого слабого устройства, как Pandora, злоупотребление сетью может стать нашим узким местом. Но я еще не проводил никаких тестов, так что это всего лишь предположение.

MPI, кажется, популярен для передачи сообщений, но он, похоже, излишним для того, что мы хотим. Этот код никогда не соприкасается с кластером или не требует сложных вычислений.

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

Ответы [ 3 ]

2 голосов
/ 16 июня 2009

Сеть также будет использовать блокировку. Он будет там, где вы его не увидите, в ядре ОС.

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

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

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

1 голос
/ 16 июня 2009

Поскольку это небольшая платформа, возможно, стоит рассчитать оба подхода.

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

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

0 голосов
/ 16 июня 2009

Я согласен с рекомендацией Зана по возможности передавать сообщения в память.

Одной из причин является то, что вы можете передавать сложные объекты C ++ без необходимости их маршалировать и демаршировать (сериализовать и десериализовать).

Стоимость защиты вашей очереди сообщений с помощью семафора, скорее всего, будет меньше, чем стоимость сетевых вызовов кода.

Если вы защищаете свою очередь сообщений с помощью некоторого безблокировочного алгоритма (используя атомарные операции, как вы намекали на себя), вы можете избежать много переключений контекста в ядро ​​и из него.

...