我正在开发一款针对手持硬件(Pandora)的C ++ RTS游戏。作为参考,Pandora有一个大约600Mhz的ARM处理器并运行Linux。我们正在尝试建立一个良好的消息传递系统(内部和外部),这对我来说是一个新领域。
举一个我们想要传递的信息的例子可能会有所帮助。一个单元可以进行此调用以将其模型加载到内存中:
sendMessage("model-loader", "load-model", my_model.path, model_id );
作为回报,该单元可能期望某种消息包含特定model_id的模型对象,然后可以将其传递给图形系统。请注意,此sendMessage函数绝不是最终的。它只反映了我目前对消息传递系统的理解,这可能不正确:)
据我所知,有两个截然不同的选择。一种是在内存中传递消息,只在需要与外部机器通信时才通过网络。我喜欢这个想法,因为开销似乎很低,但是这里的一个大问题是你需要在你的消息队列中大量使用互斥锁。如果可能的话,我真的想避免过度锁定。我已经阅读了几种方法来实现简单的队列而不需要锁定(通过依赖原子int
操作),但是这些方法假设队列中只有一个读取器和一个写入器。这对我们的特定情况似乎没有用,因为对象的队列将有许多编写器和一个读取器。
另一种选择是完全通过网络层。这有一些有趣的优点,例如免费获取异步消息。此外,我们还可以使用与本地传递完全相同的调用将消息传递到其他计算机。但是,这个解决方案让我误解了,可能是因为我不完全理解它:)我们是否需要一个套接字用于每个将要发送/接收消息的对象?如果是这样,这似乎过分了。给定的游戏将有数千个对象。对于像Pandora这样功能不足的设备,我担心像这样滥用网络可能最终成为我们的瓶颈。但是,我还没有进行任何测试,所以这只是推测。
MPI似乎在消息传递方面很受欢迎,但它确实对我们想要的东西感觉有点过分。此代码永远不会触及群集或需要进行繁重的计算。我们非常感谢您对实现此目标的选择有任何了解。
答案 0 :(得分:2)
网络也将使用锁定。在操作系统内核中,它只是你无法看到的地方。
我要做的是创建您自己的消息队列对象,您可以根据需要重写该对象。从简单开始,根据需要使其更好。这样,您可以在幕后使用您喜欢的任何实现,而无需更改其余代码。
查看您将来可能要做的几种可能的实现,并设计您的API,以便在决定按照这些条款实施时,您可以有效地处理它们。
如果你想要真正有效的消息传递,请查看一些开源L4微内核。那些人把很多时间用于快速传递消息。
答案 1 :(得分:1)
由于这是一个小平台,因此两种方法的定时可能都值得。
但是,除非出现某种大速度问题,否则我总是会采用更简单的编码方法。这可能是使用网络堆栈,因为无论收件人在哪里,它都是相同的代码,您不必手动编码和删除相互排除,消息缓冲,分配等。
如果您发现它太慢,您可以随后使用内存重新编码本地内容。但是,如果你不必这么做,为什么要浪费时间做这件事?
答案 2 :(得分:0)
我同意Zan的建议,即尽可能在内存中传递消息。
一个原因是你可以传递复杂的C ++对象而无需编组和解组(序列化和反序列化)它们。
使用信号量保护邮件队列的成本很可能低于进行网络代码调用的成本。
如果使用一些无锁算法保护您的消息队列(使用您自己提到的原子操作),可以避免很多上下文切换进出内核。