2017-09-01 90 views
1

给定一个同步程序(Minecraft),当世界正在生成时需要处理x光照更新。提高性能的一项技术是将Minecraft修补程序改为排队照明更新,然后异步处理它们,从队列中删除任何重复的预定照明更新。缓慢线程处理的缓解技术

这是为了提供一些重复删除,以及在接下来的几个滴答周期中分散世代的负载。

这个队列当前是无界的,并且在重复的位置检查之前,当队列长到可笑的大小时,将是性能差或内存泄漏的来源。

如果队列增长得​​快,它正在处理的情况下,你能做些什么来解决内存泄漏?是否有技术强制线程获得更多时间,或阻塞直到队列长度达到一定长度?我们无法提供背压,因为这会导致丢失的照明更新,而这些更新不一定会被重新安排。在有希望的处理之前也可能具有最大排队时间可能是理想的。

我会提供代码,/以更抽象的方式提问,但我不确定具体情况。

回答

2

除了将睡眠语句放入它之外,您不能减慢线程的速度。你可以玩线程优先级,但这只是改变线程的排序顺序。这可能会减慢线程的速度,但只有在优先级较高的线程占用全部运行时间的情况下。

你需要的是某种形式的作品数量调节的,而不是一个工作速度调节器。也就是说,试图只做底层机器可以完成的工作。你可能想看看ZeroMQ:这将是一个很大的体系结构变化(一开始就是异步的),但坚持一会儿。

用ZeroMQ编程是Actor模型;线程向下传递套接字,这就像消息队列一样。美丽之处在于,这些套接字的方式不仅仅是点对点链接;也有模式。例如,您可能有8个线程正在进行照明。您可以通过一个PUSH/PULL套接字将照明请求发送给这些人;可用的那个将会选择该消息并处理它。您还可以配置该套接字,以便如果达到高水位标记(灯光线程没有跟上),则新的灯光请求消息将取代队列中的旧灯光请求消息(灯光线程只会处理尽可能多的实际情况,偏差对最新的)。

而插座可以去网络连接上了。您可以在几台计算机上分发它,而几乎没有任何代码更改。

有这个建议我的问题:你会连载和deserialising对象非常多。你会撕毁现有的架构。但是您将利用通信框架来分发,扩展并以有用的方式实现负载平衡和队列管理。尝试一下会很有趣!

编辑回应评论

有一件事我能想到的是一个时间的日提交字段添加到照明要求,并具有照明线(S)计算初始之间的时间每个请求的提交以及完成处理的时间。这个执行时间测量可用于更新所有灯光线程的平均完成时间值(将其放置在由互斥锁守护的共享内存中,或类似的东西)。

事情提交照明的要求,然后可以参考这个平均水平,如果它的增加,应该在速度趋缓。同样,如果平均处理时间在减少,它可能会提高速度。如果计算机本身开始忙于在后台执行其他操作,则会适应执行时间的短缺。

实际上,这是建筑照明处理分析到应用程序,喂养回提交者,并且是多么每秒许多照明请求可以不下降太落后了提交执行过程中学习。

这将有保证队列本身并没有太充分和无限增长的副作用。它并没有将队列限制在任何特定的长度上,但是它限制了队列前后之间的时间。所以在一台速度更快的机器上,队列的平均时间会更长,而更慢的机器上的时间会更短。在CPU的

当然

热管理,一个“快”和“慢”电脑的定义是有点这几天复杂。如果确定需要大量运行时间,现代英特尔/ AMD CPU(以及大量的ARM)将提高其时钟频率。所以当CPU需要Turbo模式时,可以持续的照明请求速率将会增加,提高时钟频率,运行速度更快。因此,通过适应在达到时间目标时可以维持的速率(即保持平均完成时间合理),您的代码将会利用CPU的更高速度,因为它适应了您要求的工作负载做。

你需要小心一点,虽然;不断变化的时钟速度并不是瞬间的 - 我看到300毫秒的延迟,在整个机器的任何地方都没有发生任何事情 - 当它们发生时,看起来所有事物都突然花费了300毫秒。这就是为什么需要“平均”完成时间的原因 - 它会消除测量中的波动。

获得的平均权将此事太长度,否则你会陷入这样一种情况:你的代码的CPU和CPU的时钟频率上的需求将oscilate:

  • 您的代码窗口的工作量,
  • CPU通过加大了时钟频率响应,这需要300ms以内完成,
  • 代码检测到意外跳延迟和减少了工作量,
  • 的CPU注意到的需求下降,降低了时钟速率,
  • 你的代码了补偿,并减少工作量更加
  • 延迟再次降低,再次
  • 开始...

而且你将要步入正轨的工作量,即使平均完成时间已经达到稳定。如果这样做可以推动CPU提高其时钟频率,并且可以完成更多的照明请求,而不会影响完成时间。

基本上要被增加的工作量,且仅减少它,如果等待时间实际上增加,但在时间尺度比CPU本身的热管理/时钟管理周期较慢这样做。

+0

感谢您的回答,我很欣赏对学习目的的回应,但不幸的是,引入新框架并不是真正的解决方案,因为我们正在修补和逆向设计基本的Minecraft游戏。 你有关于工作量调节装置VS的工作速度调节器,将需要最少干预的标准Java8线程处理,或将有适当的集合/线程/执行人也许有些图书馆的进一步信息? –

+2

@RyanTheLeach不用担心。我在自我分析的基础上增加了一个想法,直到答案结尾,这应该很好地适应标准的Java线程/互斥/共享内存。祝你好运! – bazza

+1

**可爱的阅读,@ bazza **(一如既往)。除了CPU硬连线散热管理之外,最近人们还应该注意主板实现的“外部”电源冲击影响,观察这些影响是为了解决极端HPC基础架构中的问题(对需要电源的关键部分进行右调整具有不利影响在最大限度上,而不是“绿色” - 生态恐怖主义导致的恶化......有趣的是,LLNL HPC专家找到一种方法来应对这种新型外型系统性能杀手“幽灵” “)。 – user3666197

1

如何解决内存泄漏的情况下,如果队列增长更快,那么它正在处理?

在这种情况下,增加内存占用空间可能是您最小的问题。

是否有强制线程获得更多时间或阻塞,直到队列长度低于一定长度的技术?

Java线程可以优先化,但如果导致可观察到的效果,则它非常依赖于底层操作系统。

除了上述内容之外,很难提供帮助 - 您会看到,因为这非常依赖于架构/实现的细节。我会考虑如下问题:

  • 是否有足够的线程?
  • 是对预期流量足够强大的底层硬件吗?

你看 - 看起来你不能影响你的系统流入的事件数为。所以你只需要设计一个解决方案,为该流程工作。这是一个特定的问题,需要你坐下来,简介你的主题,例如:了解他们在哪里以及如何度过他们的时间。例如,结论可能是,执行这些计算的机器没有足够的马力。但是必须做的事情。

+0

如果异步负荷增长太多,我们有可能拖慢游戏处理/滴答速度,没有达到内存限制。我们无法直接控制需要生成的照明更新数量,但我们可能会放慢“主要”线程,以便再次将队列处理为可管理的数量,即做一些*同步*照明更新。我希望看到指向某种资源的链接,该资源描述了一些可能支持此功能的模式/队列/体系结构设计。 –