在C+内手动展开循环+;Introsort运行不正确 我在C++中编写了一个简单的就地内省排序,在这里我试图手动地在分区函数中展开一个循环,以便优化。我将在下面介绍这个程序,它可以编译,但不能对随机列表进行正确排序

在C+内手动展开循环+;Introsort运行不正确 我在C++中编写了一个简单的就地内省排序,在这里我试图手动地在分区函数中展开一个循环,以便优化。我将在下面介绍这个程序,它可以编译,但不能对随机列表进行正确排序,c++,optimization,quicksort,loop-unrolling,C++,Optimization,Quicksort,Loop Unrolling,该程序正在针对RISC-V架构进行编译,即使在-Ofast下,(riscv-64-unknown-elf-gcc)gcc似乎也不会自行展开循环,在每个循环中进行手动检查,以确保满足最终条件。我希望将此签出分隔开,以尝试最大限度地提高性能-据我所知,某些编译器在默认情况下会这样做 我试着将这个循环分成5个部分,以在我进一步研究之前证明这个概念(可能是多个部分,例如,尝试通过32个组,然后尝试通过16个组等等),然后像我之前做数组的最后几个元素。在展开之前,程序运行良好,但现在排序失败,我不知道如何

该程序正在针对RISC-V架构进行编译,即使在-Ofast下,(riscv-64-unknown-elf-gcc)gcc似乎也不会自行展开循环,在每个循环中进行手动检查,以确保满足最终条件。我希望将此签出分隔开,以尝试最大限度地提高性能-据我所知,某些编译器在默认情况下会这样做

我试着将这个循环分成5个部分,以在我进一步研究之前证明这个概念(可能是多个部分,例如,尝试通过32个组,然后尝试通过16个组等等),然后像我之前做数组的最后几个元素。在展开之前,程序运行良好,但现在排序失败,我不知道如何继续

下面是有问题的配分函数:

int* partition(int *startptr, int *endptr) {
    int x = *endptr; // threshold
    int *j, tmp, tmp2, *i = startptr - 1;
    for (j = startptr; j+5 < endptr; j+=5) {

        int pj = *j;
        if (pj <= x) {
            i += 1;
            tmp = *i;
            *i = pj;
            *j = tmp;
        }

        pj = j[1];
        if (pj <= x) {
            i += 1;
            tmp = *i;
            *i = pj;
            *j = tmp; }

        pj = j[2];
        if (pj <= x) {
            i += 1;
            tmp = *i;
            *i = pj;
            *j = tmp; }

        pj = j[3];
        if (pj <= x) {
            i += 1;
            tmp = *i;
            *i = pj;
            *j = tmp; }

        pj = j[4];
        if (pj <= x) {
            i += 1;
            tmp = *i;
            *i = pj;
            *j = tmp; }
        }

    j -= 5; 
    for (int *y = j; y < endptr; y++) {
        int py = y[0];
        if (py <= x) {
            i += 1;
            tmp = *i;
            *i = py;
            *y = tmp;
            } 
        }

    int *incrementedi = i + 1;
    tmp = *incrementedi;   //p[i+1]
    tmp2 = *endptr; //p[end]
    *endptr = tmp;
    *incrementedi = tmp2;
    return i + 1;
 }
int*分区(int*startptr,int*endptr){
int x=*endptr;//阈值
int*j,tmp,tmp2,*i=startptr-1;
对于(j=startptr;j+5如果(pj此示例代码有效,则在64位模式下(更多寄存器)的速度将提高约11%。编译器通过tmp优化了pj[…]的比较和条件副本,以使用寄存器(并在寄存器之间循环以允许一些重叠)

int*分区(int*plo,int*phi)
{
int*pi=plo;
int*pj=plo;
int pvt=*phi;
int tmp;
int*ph8=φ-8;
对于(pj=plo;pj
此示例代码在64位模式下工作,大约快11%(更多寄存器)。编译器通过tmp优化pj[…]的比较和条件副本,以使用寄存器(并在寄存器之间循环以允许一些重叠)

int*分区(int*plo,int*phi)
{
int*pi=plo;
int*pj=plo;
int pvt=*phi;
int tmp;
int*ph8=φ-8;
对于(pj=plo;pj
我不太喜欢模板元编程,但我也不太喜欢手动优化。在这种情况下,您可能不想使用模板让编译器为您生成这些内容吗?我到处都听说过,这似乎是一个不错的主意-我真的不熟悉这个概念/实现hough。我会进一步研究,但如何创建一个模板呢?我想举个例子,但我担心事情可能会混淆。也许我们应该首先用这个问题来解决循环的问题;然后,如果你有工作代码,你可以在这里(或在CodeReview上)发布一个单独的问题我很乐意提供一个模板版本。好的!一旦我能够让这个概念证明工作起来,并看到它对ins的影响
int * Partition(int *plo, int *phi)
{
    int *pi = plo;
    int *pj = plo;
    int pvt = *phi;
    int tmp;
    int *ph8 = phi - 8;
    for (pj = plo; pj < ph8; pj += 8)
    {
        if (pj[0] < pvt)
        {
            tmp = pj[0];
            pj[0] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[1] < pvt)
        {
            tmp = pj[1];
            pj[1] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[2] < pvt)
        {
            tmp = pj[2];
            pj[2] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[3] < pvt)
        {
            tmp = pj[3];
            pj[3] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[4] < pvt)
        {
            tmp = pj[4];
            pj[4] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[5] < pvt)
        {
            tmp = pj[5];
            pj[5] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[6] < pvt)
        {
            tmp = pj[6];
            pj[6] = *pi;
            *pi = tmp;
            ++pi;
        }
        if (pj[7] < pvt)
        {
            tmp = pj[7];
            pj[7] = *pi;
            *pi = tmp;
            ++pi;
        }
    }
    for (; pj < phi; ++pj)
    {
        if (*pj < pvt)
        {
            tmp = *pj;
            *pj = *pi;
            *pi = tmp;
            ++pi;
        }
    }
    tmp  = *phi;
    *phi = *pi;
    *pi  = tmp;
    return pi;
}

void QuickSort(int *plo, int *phi)
{
int *p;
    if (plo < phi)
    {
        p = Partition(plo, phi);
        QuickSort(plo, p-1);
        QuickSort(p+1, phi);
    }
}