你可以在O(n / p)时间内进行并行计数排序吗?

时间:2016-10-06 18:26:39

标签: algorithm sorting parallel-processing counting-sort

是否可以并行进行计数排序并实现O(n / p)运行时间?

举一个例子,我们有一个包含数百万个元素的数组,范围从1-10。合并排序的运行时间不会超过O(nlogn)时间。应用于此问题的计数排序将在O(n)时间内运行。并行计数排序可能很有趣。如果我们为每个处理器分配一个带有n / p元素的子阵列,并且每个处理器都有自己的大小为9的计数数组,那么累积元素计数的初始步骤应该花费O(n / p)时间。将所有计数数组合并为单个数组应该花费O(p)时间,因为您只迭代p计数数组,每个数组都是常量。

我还没有能够完全考虑计数排序的最后一步,其中元素按顺序排列。如果count数组的元素是原子的,你可以将原始数组的n / p部分分配给各个处理器并实现一些并行化,但是计数数组的各个元素会有争用,可能会大大减少并行化。如果输入数组全部为10,则所有处理器将在计数数组的第9个元素上序列化,从而将算法效率降低到O(n)。

您可以将count数组的子数组分配给每个p处理器,然后返回O(n / p)运行时,但前提是元素的分布相当均匀。而且,在我们的示例中,您将被限制为10个处理器。如果元素不均匀分布,则一个或多个处理器可以执行更大比例的工作。例如,如果输入数组中的一半元素是10,则一个处理器必须逐步通过该数组的一半。最糟糕的情况是,阵列全部都是10,并且单个处理器必须逐步完成将运行时间转换为O(n)的整个阵列。

也许你可以在多个处理器之间划分计数数组的各个元素。例如,如果输入数组中有50个10,则计数数组的元素9将反映这一点。您可以让5个处理器将10 10个写入输出数组中的正确位置。如果在count数组的每个索引位置有少于p个元素,则这又转换为O(n)运行时,但它避免了元素值分布不均匀的问题。

是否可以在O(n / p)时间内进行计数排序?

1 个答案:

答案 0 :(得分:2)

是的,有可能。将数组除以p等长的部分。然后为每个进程创建一个计数数组'c'。让每个进程计算元素的数量并将它们存储在c中。这将需要O(n/p)。现在将所有计数数组c加在一起,并将数组共享给所有进程。这将采用O(p*b),其中b是可能值的数量。到目前为止,这正是您的方法。现在,您可以在p进程中重新创建数组,因为您可以从c计算值的第一个和最后一个索引。对于每个值i,其第一个索引是c中所有先前值的总和。它的最后一个索引是它的第一个索引加c[i]。此计算可以在O(i)中完成,其中i小于b,因此小于O(b)。每个流程现在都可以重新填充自己的部分。这又需要O(n/p)。总而言之,你有n/p + p*b + b + n/p。如果p*b << n,则会生成O(2*n/p)。 (由于2/p是一个常数因子,您仍然拥有类O(n)。但并行化将显着加快您的算法速度。)