Pregunta

Estoy trabajando en un juego de estrategia en tiempo real en C ++ dirigido a hardware de mano (Pandora). Para referencia, Pandora tiene un solo procesador ARM a ~ 600Mhz y ejecuta Linux. Estamos intentando establecer un buen sistema de transmisión de mensajes (tanto interno como externo), y para mí este es un nuevo territorio.

Puede ser útil dar un ejemplo de un mensaje que nos gustaría transmitir. Una unidad puede hacer esta llamada para cargar sus modelos en la memoria:

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

A cambio, la unidad podría esperar algún tipo de mensaje que contenga un objeto modelo para el model_id particular, que luego se puede pasar al sistema de gráficos. Tenga en cuenta que esta función sendMessage no es definitiva. Simplemente refleja mi comprensión actual de los sistemas de paso de mensajes, lo que probablemente no sea correcto :)

Por lo que puedo decir, hay dos opciones bastante distintas. Una es pasar mensajes en la memoria y solo pasar a través de la red cuando necesite hablar con una máquina externa. Me gusta esta idea porque la sobrecarga parece baja, pero el gran problema aquí es que parece que necesita hacer un uso extensivo del bloqueo de mutex en las colas de mensajes. Realmente me gustaría evitar el bloqueo excesivo si es posible. He leído algunas formas de implementar colas simples sin bloquear (confiando en las operaciones atómicas int ) pero estas suponen que solo hay un lector y un escritor para una cola. Esto no parece ser útil para nuestro caso particular, ya que la cola de un objeto tendrá muchos escritores y un lector.

La otra opción es ir completamente sobre la capa de red. Esto tiene algunas ventajas divertidas, como conseguir que los mensajes asíncronos pasen de forma gratuita. Además, obtenemos la capacidad de pasar mensajes a otras máquinas utilizando exactamente las mismas llamadas que los que se pasan localmente. Sin embargo, esta solución me molesta, probablemente porque no lo entiendo completamente :) ¿Necesitaríamos un socket para cada objeto que va a enviar / recibir mensajes? Si es así, esto parece excesivo. Un juego dado tendrá miles de objetos. Para un dispositivo con poca potencia como el Pandora, me temo que abusar de la red de esa manera puede terminar siendo nuestro cuello de botella. Pero aún no he realizado ninguna prueba, así que esto es solo una especulación.

MPI parece ser popular para el paso de mensajes, pero seguro que parece una exageración por lo que queremos. Este código nunca tocará un clúster o tendrá que hacer un cálculo pesado.

Cualquier información sobre las opciones que tenemos para lograr esto es muy apreciada.

¿Fue útil?

Solución

La red también usará bloqueo. Solo estará donde no pueda verlo, en el kernel del sistema operativo.

Lo que haría es crear su propio objeto de cola de mensajes que puede reescribir como sea necesario. Comience de manera simple y hágalo mejor según sea necesario. De esa manera, puede hacer que use cualquier implementación que desee entre bambalinas sin cambiar el resto de su código.

Mire varias implementaciones posibles que le gustaría hacer en el futuro y diseñe su API para que pueda manejarlas de manera eficiente si decide implementar en esos términos.

Si desea pasar un mensaje realmente eficiente, observe algunos de los micro-núcleos L4 de código abierto. Esos tipos dedican mucho tiempo a pasar el mensaje rápidamente.

Otros consejos

Ya que esta es una plataforma pequeña, podría valer la pena programar ambos enfoques.

Sin embargo, salvo algún tipo de problema de gran velocidad, siempre optaría por un enfoque más sencillo de codificar. Probablemente va a usar la pila de red, ya que será el mismo código sin importar dónde se encuentre el destinatario, y no tendrá que codificar y depurar manualmente sus exclusiones mutuas, almacenamiento en búfer de mensajes, asignaciones, etc.

Si descubres que es demasiado lento, siempre puedes volver a codificar las cosas locales usando la memoria. Pero, ¿por qué perder el tiempo haciendo eso por adelantado si no es necesario?

Estoy de acuerdo con la recomendación de Zan de pasar mensajes en memoria siempre que sea posible.

Una de las razones es que puede pasar objetos complejos C ++ sin necesidad de ordenarlos y desmarcarlos (serializarlos y serializarlos).

Lo más probable es que el costo de proteger tu cola de mensajes con un semáforo sea menor que el costo de hacer llamadas de código de red.

Si protege su cola de mensajes con algún algoritmo sin bloqueo (utilizando operaciones atómicas como usted aludió a usted mismo), puede evitar mucho que un contexto entre y salga del kernel.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top