前几天我在考虑创建一个小型的生活模拟器。我只是忽略了这个想法,我想知道最好的实施方式,以便它能够高效运行。
在最低级别会有男性和女性实体在周围徘徊,当他们见面时,他们会产生后代。
我想使用多线程来管理实体,但我不确定线程的数量等。
最好有几个线程来管理男性和女性,或者可以为每个实体启动一个线程,以便每个实例都在自己的线程上运行吗?
我已经阅读了一些关于最大线程数的帖子以及应用中20-1000个线程的限制范围。
任何人对架构都有任何建议吗?
<磷>氮答案 0 :(得分:15)
每个实体都没有一个线程。这是灾难的秘诀。这不是线程的设计目标。线程非常重量级;记住,每个线程立即消耗一百万字节的虚拟地址空间 。此外,请记住,每当两个线程在共享数据结构上进行交互时(如模拟世界),他们需要取出锁以防止损坏。你的程序将是数百个被阻塞线程的 mass ,被阻塞的线程是无用的;他们无法工作。高争用是良好性能的诅咒,许多共享一个数据结构的线程只不过是持续的争用。
程序中的线程数应该是一个,除非你有充分的理由拥有两个。通常,程序中的线程数应该尽可能小,尽管仍然可以获得所需的性能特征。
如果您的程序确实“令人尴尬地并行” - 也就是说,在不锁定共享数据结构的情况下并行进行计算非常容易 - 那么正确的线程数就等于处理器内核的数量。机。请记住,线程相互减慢。如果您有四个银行出纳员,并且每个都为一个客户服务,那么事情就会很快。您正在描述这样一种情况:您有四个银行出纳员(CPU核心),每个银行出纳员同时为一百个人提供服务,通过发放便士循环。
模拟很少令人尴尬地平行,因为很难将工作分解为独立的部分。例如,光线追踪是令人尴尬的平行;一个像素的内容不依赖于任何其他像素的内容,因此可以并行计算它们。但是你不会每个像素有一个线程!每个处理器有一个线程,让四个处理器中的每一个处理四分之一像素。使用模拟很难做到这一点,因为实体做彼此互动。
需要处理交互实体的高质量专业模拟器(如物理引擎)无法解决线程问题。通常,他们将有一个执行模拟的线程和一个运行用户界面的线程,因此昂贵的模拟计算不会挂起UI。
对你来说,正确的架构可能就是让一个线程像火焰一样进行模拟。计算所有实体对单个帧的交互,然后发出需要更新的UI线程的信号。这将允许您通过测量计算每个实体的所有交互所需的微秒数来确定您的最大帧速率。
答案 1 :(得分:1)
使用100s的线程(很多会睡眠())不是一个好的解决方案。你很快就会耗尽内存。
TPL可能会让这个想法变得可行,但它并没有真正为此设计。
研究离散事件模拟和光纤。有用于.NET的伪光纤库
答案 2 :(得分:1)
我假设您的应用程序以delta-Ts管理时间线。
您可以使用C#4.0的并行框架并使用TASK而非线程。
每个delta-T都运行parallel-for来更新实体。
并行框架将决定打开和管理线程的线程数。