2

我创建了一个中位数为 3 的标准快速排序实现,它对大量随机整数进行排序。我想增加到至少 1 亿个元素,但最好是 10 亿个。为了提高速度,我尝试在 Cilk++ 中并行化算法。该算法使用双递归,我生成 Cilk 任务来执行每个递归排序。

我的算法适用于最大为 10 000 000 的数组。没有 Cilk 关键字,我的顺序算法可以轻松处理 1 亿个元素,但是当我尝试使用 Cilk 时,程序崩溃到桌面。我现在想找出原因。我是否太快地生成了太多 Cilk 任务?

我正在使用 Windows 7 64 位、Intel++ 编译器和集成在 Visual Studio 2010 中的 Intel Parallel Studio XE 2013。该程序被编译为 32 位应用程序。存储随机数据的内存被分配为对 malloc 的单个调用,并检查指针。在中值计算中,在计算中间元素时也要注意整数溢出。

这很可能是缓冲区溢出问题。

这是我的分区:

int pivotvalue = medianOf3(data, low, high);
// pivot is placed next to the last element

int left = low;
int right = high - 1;
while (left < right) {
    while (data[left] < pivotvalue) {
        left++;
        if (left > high) {
            break;
        }
    }
    while (data[right] >= pivotvalue) {
        right--;
        if (right < low) {
            break;
        }
    }

    if (left < right) {
        swap(data, left, right);
    }
}

// restore pivot
swap(data, left, high - 1);
return left;
4

3 回答 3

3

我不知道 Cilk 是如何工作的,但我记得需要在嵌入式平台上修复一个快速排序实现,该实现可能会通过递归溢出堆栈。解决方法是对较小的“一半”数据使用递归调用,并在函数内部处理较大的“一半”(即尾递归)。排序(或反向排序)列表总是会触发溢出,因为调用图的深度等于列表中元素的数量。

您可以使用调试器找出导致崩溃的原因吗?您能否将数据转储到每个条目的日志文件中swap(),然后查看崩溃前函数调用的样子?是否可以在每次调用时转储堆栈的大小? 每个 Cilk 任务是否都有自己的堆栈,可能小于非 Cilk 版本中使用的堆栈?

swap()您可以通过向堆栈地址添加参数来跟踪堆栈使用情况。第一次调用和任何新的 Cilk 线程都使用 NULL。如果不是 NULL,则每个递归调用都使用该参数,或者使用其局部变量之一的地址来确定其堆栈的位置。转储地址差异,或在全局中跟踪它,仅在超过之前的最大值时才报告。

于 2012-11-08T18:39:10.963 回答
2

英特尔 Cilk Plus(cilk++ 是不支持的不同产品)对 1024 的生成深度有限制。完全有可能溢出双端队列,这会导致崩溃。

决定在递归树中产生多深是一种平衡行为。您希望有足够的生成以允许工作被盗,但使用太多会增加开销。cilk_spawn 很便宜,但它不是免费的。如果要排序的元素数量低于某个阈值,最好在快速排序中添加一个检查,并且不要产生递归调用。

cilk_for 的好处之一是它可以根据您运行的工人数量优化产卵深度。

- Barry Tannenbaum
  Intel Cilk Plus Runtime Development
于 2013-02-13T15:08:23.567 回答
2

对两个子问题递归的 N 个项目的快速排序具有(最坏情况)递归深度 O(N)。通常的解决方法是“tomlogic”建议的解决方法:递归较小的子问题,迭代较大的子问题。这将递归深度减少到 O(lg N)。

该修复程序延续到并行版本。如果串行程序占用堆栈空间 S,Cilk Plus 版本最多占用堆栈空间 PS。(这个属性不适用于许多其他并行框架。)因此产生较小的子问题并迭代较大的子问题应该使总堆栈空间保持在 O(P lg N) 内。

我是Structured Parallel Programming一书的作者之一,该书讨论了在 Cilk Plus 和 TBB 中 Quicksort 的并行实现。快速排序的示例(完全递归和半递归)可以从http://parallelbook.com/student免费下载。

Arch D. Robison
Intel Corporation
于 2013-02-13T16:39:21.540 回答