4

我正在执行一项操作,我们称之为CalculateSomeData。CalculateSomeData 在连续的“代”中运行,编号为 1..x。整个运行中的代数由CalculateSomeData的输入参数固定,并且是先验已知的。单代需要 30 分钟到 2 小时才能完成。其中一些可变性是由于输入参数造成的,并且无法控制。但是,这种可变性的一部分是由于硬件容量、来自其他进程的 CPU 负载、网络带宽负载等因素造成的。每代可以控制的一个参数是 CalculateSomeData 使用的线程数。现在这是固定的并且可能不是最佳的。一世' 我想跟踪每一代所花费的时间,然后有一些算法来调整线程的数量,以便每一代后续的计算时间都在前一代的计算时间上有所改进(最小化时间)。我应该使用什么方法?遗传算法的适用性如何?直觉告诉我,这个范围会相当小——在双四核处理器机器上可能有 1 到 16 个线程。

非常感谢任何指针、伪代码等。

4

3 回答 3

2

如果计算完全受 CPU 限制,则线程数应等于机器上的内核数。这样可以最大限度地减少上下文切换的数量。

如果您的计算涉及 I/O、网络、同步或其他阻碍执行的东西,您必须找到限制资源并测量利用率。您需要监控利用率并慢慢添加更多线程,直到利用率接近 100%。你应该有尽可能少的线程来饱和你的限制资源。

于 2010-09-21T17:14:17.613 回答
2

进化算法怎么样。

从猜测开始。每个 CPU 核心 1 个线程似乎不错,但取决于手头的任务。

测量一代中每个任务的平均时间。将其与上一代所花费的时间进行比较。(假设第 0 代有效地无限时间和 0 个线程)。

如果最近一代任务的平均时间比之前的要好,继续沿与上一步相同的方向更改线程数(因此,如果上一代的线程比上一代的线程多,则为新一代,但如果它更少,则使用更少(显然下限为 1 个线程)。

如果最近生成的任务平均比上一代花费更长的时间,则在相反方向更改线程数(因此,如果增加线程数导致时间更糟,则下次少使用一个线程)。

只要最佳线程数不太接近 1,那么您最终可能会在 3 个都合理接近最佳值的值之间波动。如果您有大量的世代需要处理,您可能希望显式检测这种情况并将自己锁定在中心值中。

于 2010-09-22T11:00:30.833 回答
1

您应该将您的世代分成许多小任务并将它们排成队列。每个核心产生一个线程,让每个线程执行一个任务,运行它完成,然后重复。

您需要比内核更多的任务,以确保您不会在生成结束时只运行一个任务而所有其他线程都处于空闲状态。如果您按照 Albin 的建议设置 #tasks = #threads = #cores,则可能会发生这种情况(除非您可以确保所有任务都花费完全相同的时间)。

您也可能不想要比内核更多的线程。上下文切换并不是非常昂贵,但是同时活动的 #cores 多个任务所带来的更大的缓存占用可能会伤害您(除非您的任务使用很少的内存)。

于 2010-09-21T20:05:38.070 回答