Pergunta

Eu estou trabalhando em um jogo RTS em C ++ orientada para hardware portátil (Pandora). Para referência, o Pandora tem um único processador ARM em ~ 600Mhz e roda Linux. Estamos tentando resolver em um sistema que passa boa mensagem (interna e externa), e este é um território novo para mim.

Ela pode ajudar a dar um exemplo de uma mensagem que gostaríamos de passar. Uma unidade pode fazer esta chamada para carregar seus modelos na memória:

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

Em troca, a unidade poderia esperar algum tipo de mensagem que contém um objeto de modelo para o model_id particular, que pode então ser passado para o sistema de gráficos. Por favor, note que esta função sendMessage não é de forma final. Ele só reflete o meu entendimento atual de sistemas de passagem de mensagens, o que provavelmente não é correta:)

De que eu posso dizer há duas opções bastante distintas. Um deles é para passar mensagens na memória, e só passar através da rede quando você precisa falar com uma máquina externa. Eu gosto desta idéia, porque a sobrecarga parece baixo, mas o grande problema aqui é que parece que você precisa fazer uso extensivo de bloqueio mutex em suas filas de mensagens. Eu realmente gostaria de evitar o excesso de bloqueio, se possível. Eu li algumas maneiras de implementar filas simples, sem bloqueio (por depender de operações int atômicas), mas estas assumem há apenas um leitor e um escritor para uma fila. Isso não parece útil para nosso caso particular, como fila de um objeto terá muitos escritores e um leitor.

A outra opção é ir completamente sobre a camada de rede. Isto tem algumas vantagens divertidas como a obtenção de passagem de mensagens assíncronas praticamente de graça. Além disso, ganhamos a capacidade de passar mensagens para outras máquinas usando exatamente as mesmas chamadas como passar localmente. No entanto, esta solução esfrega-me o caminho errado, provavelmente porque eu não compreender totalmente o :) Será que precisamos de uma tomada para cada objeto que vai ser envio / recebimento de mensagens? Se assim for, isso parece excessiva. Um jogo dado terá milhares de objetos. Para um dispositivo um pouco fraca potência como o Pandora, temo que abusar da rede como esse pode acabar sendo o nosso gargalo. Mas, eu não ter executado todos os testes ainda, então isso é apenas especulação.

MPI parece ser popular para a passagem de mensagens, mas com certeza se sente como um exagero para o que queremos. Este código é nunca vai tocar em um cluster ou necessidade de fazer cálculos pesados.

Qualquer visão sobre o que opções que temos para realizar isso é muito apreciado.

Foi útil?

Solução

A rede será usando bloqueio bem. Será apenas onde você não pode vê-lo, no kernel OS.

O que eu gostaria de fazer é criar seu próprio objeto fila de mensagens que você pode reescrever como você precisa. Comece simples e torná-lo melhor, conforme necessário. Dessa forma, você pode fazê-lo usar qualquer implementação você gosta nos bastidores, sem alterar o resto do seu código.

Olhe para várias implementações possíveis que você gostaria de fazer no futuro e projetar sua API para que você possa lidar com todos eles de forma eficiente se você decidir implementar nesses termos.

Se você quiser mensagem realmente eficiente passando olhada em alguns dos micronúcleos L4 de código aberto. Esses caras colocar um muito do tempo em passagem de mensagens rápido.

Outras dicas

Uma vez que esta é uma pequena plataforma, pode valer a pena momento ambas as abordagens.

No entanto, salvo algum tipo de problema de grande velocidade, eu sempre ir para a abordagem que é mais simples de código. Isso é provavelmente vai estar usando a pilha de rede, uma vez que será o mesmo código, não importa onde o destinatário é, e você não terá de código manualmente e degug seu exclusões mútuas, mensagem de tamponamento, atribuições, etc.

Se você descobrir que é muito lento, você sempre pode recodificar o material local usando memória mais tarde. Mas por que perder tempo fazendo isso da frente para cima, se você não pode ter que?

Eu concordo com a recomendação do Zan para passar mensagens na memória sempre que possível.

Uma das razões é que você pode passar objetos complexos C ++ sem a necessidade de marechal e unmarshal (serialize e de-serialize)-los.

O custo de proteger a sua fila de mensagens com um semáforo é mais provável vai ser menor do que o custo de fazer networking chamadas de código.

Se você proteger sua fila de mensagens com algum algoritmo de livre-lock (usando operações atômicas como você aludiu a si mesmo), você pode evitar uma série de mudanças de contexto para dentro e para fora do kernel.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top