0

我正在开发游戏模拟游戏,并希望加快比赛模拟速度。在给定日期,可能有 50 多个匹配项需要模拟。目前我遍历每个并告诉他们模拟自己,但这可能需要很长时间。我希望

1)覆盖一个“忙碌”的屏幕

2)为每个启动一个线程

3)当最后一个线程退出时,移除覆盖层。

现在我可以做 1 和 2,但我不知道如何判断最后一个线程何时完成,因为我分离的最后一个线程可能不是最后一个线程完成。最好的方法是什么?

此外,通常使用线程以便在用户执行其他操作时可以在后台完成工作,我使用它略有不同。我的应用程序是一个核心数据应用程序,我想避免用户在模拟比赛时以其他方式接触商店。所以我大部分时间都想要单线程,但是由于 sim 引擎需要多长时间,所以在这种情况下使用多线程。如果有人对这种方法有其他想法,我很开放。

4

5 回答 5

2

很可能您想使用 NSOperation 而不是 50 个线程 - 50 个线程在 iPhone 上并不健康,而且 NSOperation 更容易启动。尝试一次运行 50 次可能会降低性能(这是我的猜测)。NSOperation 正是针对这个问题而设计的。加上它易于编码。

我对 NSOperation 的唯一问题是他们没有标准的方法来告诉调用者他们已经完成了。

您可以定期轮询 NSOperationQueue - 当它的计数为 0 时,就没有剩余了。您还可以使每个操作增加一些计数器 - 当计数为 50 时,您就完成了。或者每个操作都可以使用 performSelectorOnMainThread 在其完成的主线程上发布通知。

即使是单核,您也应该会看到性能的提升 - 很多时候主线程被阻塞等待用户输入/图形绘图/等。此外,多核手机和 iPad 可能会在一年内推出(完全猜测——但它们即将到来)。

还要确保您使用 Instruments 查看操作。您可能可以将计算速度提高 2 倍甚至 10 倍!

于 2010-09-06T17:30:58.310 回答
1

你在一个单核上,所以线程可能不会有太大帮助,而且开销甚至可能会减慢速度。

首先要做的是使用 Instruments 来分析您的代码并查看可以加速的内容。完成后,您可以查看瓶颈的一些特定优化。

一种简单的方法(如果你可以使用 GCD)是 dispatch_apply(),它可以让你循环匹配你的匹配,自动以最适合你的硬件的方式线程化它们,并且在所有都完成之前不会返回。

于 2010-09-06T15:13:21.047 回答
0

最直接的解决方案是让您的所有线程在退出之前将所有线程“执行选择器OnMainThread”用于递减计数器的特定方法。并让该方法在其递减的计数器达到零时移除覆盖屏幕。

但是,同时模拟所有匹配不一定会提高性能。

于 2010-09-06T15:19:19.063 回答
0

您可以从@drowntoge 获得针对您的特定问题的解决方案,但总的来说,我想给您一些关于多线程的建议:

1/ 并不总是像 Graham 所说的那样加速你的程序。你的 iPhone 只有单核。

2/ 如果你的程序有一些大的IO、数据库或网络进程需要时间,那么你可以考虑多线程,因为现在数据处理不是一直占用时间,它需要等待加载数据。在这种情况下,多线程将显着提高您的性能。但是你仍然需要小心,因为线程切换有开销。

也许您只需要 1 个线程进行 IO 处理,然后有一个缓存层来共享图像/数据。然后,你只需要主线程循环并做模拟

3/如果你想让50个模拟同时发生供用户观看,还需要多线程:)

于 2010-09-06T16:06:38.993 回答
0

如果您使用线程,您将不知道 CPU 执行任务的顺序,并且您可能会消耗大量线程调度资源。最好使用 NSOperationQueue 并使用 performSelectorOnMainThread 发出每个任务的完成信号。已经提到了递减计数器,这对于显示进度条可能很有用。但是您也可以维护一个包含 50 个繁忙标志的数组并在完成时清除它们,如果您使用时间戳标记完成,这可能有助于调试任何特定任务是否缓慢或卡住。

于 2010-09-06T18:46:13.340 回答