繁体   English   中英

为什么我的快速排序在大量输入时崩溃?

[英]Why does my quicksort crash on large inputs?

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

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

我正在使用Windows 7 64位,Intel ++编译器和集成在Visual Studio 2010中的Intel Parallel Studio XE2013。该程序被编译为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;

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

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

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

英特尔Cilk Plus(不支持cilk ++是另一种产品)的生成深度限制为1024。您的双端队列很可能溢出,这很可能会导致崩溃。

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

cilk_for的好处之一是,它可以根据与您一起工作的工作人员的数量来优化产卵深度。

- Barry Tannenbaum
  Intel Cilk Plus Runtime Development

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

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

我是《 结构化并行编程 》一书的作者之一,该书讨论了Cilk Plus和TBB中Quicksort的并行实现。 可以从http://parallelbook.com/student免费下载Quicksort的示例(完全递归和半递归)。

Arch D. Robison
Intel Corporation

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM