2010-04-07 67 views
0

比方说,我有一个域模型,即时尝试与多线程兼容。 原型域是由Space,SpaceObject和Location对象组成的游戏域。 SpaceObject有Move方法和Asteroid并且Ship扩展这个对象具有对象的特定属性(Ship有一个名称并且Asteroid有一个颜色)C#多线程域设计

比方说,我想让每个对象的Move方法运行在单独的线程。这将是愚蠢的,因为有10000个对象,我会有10000个线程。核心/线程之间分离工作负载的最佳方式是什么?

我正在尝试学习并发的基础知识,并构建一个小型游戏来构建很多概念的原型。

我已经做了什么,是建立一个域,并带有定时器的线程模型,该定时器根据间隔启动事件。如果发生事件,我想用任何SpaceObject的新位置更新我的整个模型。 但是我不知道在事件发生时如何以及何时用工作负载启动新线程。

有些工作人员告诉我,你无法更新你的核心域多线程,因为你必须同步一切。但在这种情况下,我无法在双核四核服务器上运行我的游戏,因为它只会使用1个CPU来完成最困难的任务。

任何人都知道该怎么办?

规格的反应Deltreme:

你是正确的是绝对,你的方法在大多数情况下工作。但是, 线程必须更新Space类中的spaceobject的位置。

比方说,我有两个SpaceObjects旁边的彼此,他们正在走向彼此。 1对象位于线程A中,另一个位于线程B中。 一旦我更新对象,线程必须一起写入空间,以在Tile(空间的单独部分)中写入新值。那个人通话不能在不同的线程同时进行,造成空间物体就会爆发......

什么都可能发生的碰撞,我可以写,如果他们有2艘@ 1瓦时发生的事件。这不是问题。

我在考虑10000艘船的情况下,CPU主要是在线程之间切换,而不是全部运行它们。因此,为了提高性能,我希望能够同时“一切”

回答

1

您可以使用System.Threading.ThreadPool或即将推出的任务并行库根据可用内核数量自动管理您的线程数。

并发问题的一种可能的方法是只锁定您当前的SpaceObject可以与之交互的其他SpaceObjects。这将在大多数情况下提供足够的性能,但在最糟糕的情况下,处理大型交互将由单个线程完成。你最终需要锁定多少取决于你的模拟参数。如果对象在定时器的单个滴答内不能完全通过对方,那么只需检查重叠对象即可离开。对于快速移动的物体,您需要检测相交的运动矢量。

+0

谢谢,这很有帮助,这意味着我可以在最坏的情况下优化0%,在最好的情况下可以优化0%。你知道有什么方法可以提高这些赔率吗? – 2010-04-07 10:03:06

0

我假设您创建快照:在情况下每个SpaceObject位于某个位置,并且在每个SpaceObject移动到另一个位置之后,您将看到情况B.

对于10000个对象,情境A和B之间的转换为10000个移动呼叫。 Move()听起来像一个相当快的方法,即。使用当前的位置和方向创建新的位置。

在这种情况下,您可以创建10个线程(或使用线程池),并指定说50个SpaceObjects到它,因为它会再计算出新的位置。如果一个线程完成了,并且仍有SpaceObjects需要移动,则可以为该线程分配另一个50。

+0

查看我更新的问题 – 2010-04-07 09:31:38

0

正如Hirvox所说,ThreadPool是一个不错的选择。我会避免用每个SpaceObject的线程来思考,而是把它想象成一个SpaceObjects的大队列,它们都需要在一个时间间隔上更新它们的位置,然后使用线程来执行移动计算。对象;这非常适合ThreadPool。它可能不是一个实际的队列,但可以是一个有序的字典,但你明白了。

当您完成移动计算后,使用类似的方法处理任何碰撞。处理快速移动者的一种方法是在非常短的时间间隔内工作,每隔一段时间更新快速移动者,每隔一段时间更新一次中等移动者,每隔十分钟更新一次慢速移动者。

只是为了好玩,请考虑使用视频卡进行计算 - 高端图形处理器针对同步计算的空白进行了优化。