分而治之总是获得更好的性能吗?

Posted

技术标签:

【中文标题】分而治之总是获得更好的性能吗?【英文标题】:Does Divide an Conquer always get better performance? 【发布时间】:2020-07-12 13:17:01 【问题描述】:

我目前正在测试一些分而治之的算法与它们的正常实现。我对此很陌生,我不确定在使用分而治之时是否应该始终获得更好的性能。例如,我已经实现了一种算法来传统地转置矩阵并使用分治法,但使用第一个版本我仍然可以获得更好的性能。有可能还是我错过了一些重要的事情?

这是使用分而治之的代码

void trasponer_DyV(Matriz &matriz)

    if (matriz.size() >= 2)
    
        trasponer_DyV(matriz, 0, matriz.size(), 0, matriz.size());
    


void trasponer_DyV(Matriz &matriz, int fil_inicio, int fil_fin, int col_inicio, int col_fin)

    int tam = fil_fin - fil_inicio;

    if (tam == 1)
        return;

    trasponer_DyV(matriz,fil_inicio, fil_inicio + tam / 2,col_inicio, col_inicio + tam / 2);
    trasponer_DyV(matriz, fil_inicio, fil_inicio + tam / 2, col_inicio + tam / 2, col_inicio + tam);
    trasponer_DyV(matriz, fil_inicio + tam / 2, fil_inicio + tam, col_inicio, col_inicio + tam / 2);
    trasponer_DyV(matriz, fil_inicio + tam / 2, fil_inicio + tam, col_inicio + tam / 2, col_inicio + tam);

    for (int i = 0; i < tam / 2; i++)
    
        for (int j = 0; j < tam / 2; j++)
            swap(matriz[fil_inicio + i][col_inicio + tam / 2 + j], matriz[fil_inicio + tam / 2 + i][col_inicio + j]);
    

这是蛮力的:

Matriz trasponer_fuerzabruta(const Matriz &matriz)

    Matriz ret;
    ret.resize(matriz.size());
    for (int i = 0; i < matriz.size(); ++i)
    
        ret[i].resize(matriz.size());
    

    // Todo lo que hacemos es sustituir filas por columnas.
    for (int fila = 0; fila < matriz.size(); ++fila)
    
        for (int columna = 0; columna < matriz.size(); ++columna)
        
            ret[columna][fila] = matriz[fila][columna];
        
    

    return ret;

提前致谢!

【问题讨论】:

你之前不是问过同样的问题吗? 我做了,但我没有添加代码,它被关闭了 要比较两种算法的性能,我们需要查看两种算法的代码。 【参考方案1】:

第一个版本做了更多的工作 - 它就地转置片段,然后将它们交换到正确的位置。

第二个版本一次转置一个元素,但已经转置到最终位置。

此外,在顺序过程中,分治法仅在工作集不适合 L3 缓存(8MB 或更多)时才有用,这相当于大小为 >1000*1000 的矩阵。

虽然并行化它(在 CPU 级别)也没有好处,因为矩阵转置是一个完全受 DRAM 限制的操作。

【讨论】:

如何优化第一个版本? 考虑如何在单次传递中成对地转置片段。考虑矩阵的对角对称性。 花了一些时间,但我明白你的意思了。非常感谢,真的很有帮助!【参考方案2】:

第一个函数预计性能更高,因为它不会进行任何额外的函数调用,这不是免费的。

恕我直言,如果:

    您可以并行使用多个处理器 -- 使用线程或类似 MPI 的环境,或者

    提高了函数的可读性(从而提高了可维护性),或者

    在概念上可以将更高级别的算法划分为更小的、可能可重用的函数。

【讨论】:

我知道所有的理论,但我看不出分治法的表现不如基础算法的原因:(

以上是关于分而治之总是获得更好的性能吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥分而治之的算法通常比蛮力运行得更快?

矩阵乘法 - 分而治之 vs Strassen,分而治之更快?

为啥分而治之在数组总和上没有表现出其性能优势?

快速排序是一种分而治之的方法吗? [关闭]

使用分而治之的最大子阵列产品有人吗?

分而治之:解决子问题明显快于未分问题是效率的一部分吗?