在实践中,已经是线性时间复杂度的算法是否需要并行化呢?我的老师认为这没有必要,但我不太相信。
在实践中,已经是线性时间复杂度的算法是否需要并行化呢?我的老师认为这没有必要,但我不太相信。
你的老师是错误的。单CPU算法的运行时间复杂度(O(n), O(log n),等等)与是否能从并行化中受益无关。
将代码从使用1个CPU改为使用K个CPU最多只能将运行时间减少K倍。由于你不能随意从空气中创建CPU,所以K实际上是一个常数。因此,并行化不会影响运行时复杂度。你所能做的只是获得一个常数因子的改进。
这并不是说没有价值——在某些情况下,两倍的改进是非常有益的。此外,在成千上万个CPU的大规模并行系统中,这个常数变得相当大。
如果输入足够大,那么它是值得的。总是如此。
例如:一个朴素的算法来查找无序列表中最大的数字只需遍历列表。这将花费O(n)
的时间来查找记录。
如果你有100个或1000个记录,这还可以接受。
如果你有10亿条记录呢?你可以将列表分成多个CPU,每个CPU找到一个最大值,然后你就有了一个新的较小列表来处理。你可以再次分割 => 并行处理,速度更快。我相信如果你有效地分割和减少,并且拥有n个CPU,那么它的时间复杂度应该是O(log(n))
。
重点是:如果你的输入足够大,O(n)
已经不够好了。根据需要完成的任务,O(n)可能会增长到比你想要的时间多出许多秒、分钟或小时。
O(n)
或 O(log(n))
时,我指的是完成搜索所需的时间,而不是所有 CPU 执行的“总工作量”。通常情况下,并行化算法会增加 CPU 执行的总工作量。假设在单核、单 CPU、单机环境下,且任务是 CPU 绑定的情况下,你的老师是正确的。(尽管可以争论,在这种情况下,即使你运行多个线程,它们也不是真正并行运行的,只是给人以并行运行的假象)
然而,现在的单核系统已经很少见了,甚至许多智能手机都开始采用多核技术,因此在实践中,你可能会从并行化中受益。我说“可能”,是因为如果任务很小,线程创建的成本将会比收益更高,同样还有上下文切换的开销。如果没有明智地进行操作,使一个操作并行化实际上可能会使其变得更慢。