征服征服者始终可以获得更好的性能吗?

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

这是使用分而治之的代码

void trasponer_DyV(Matriz &matriz)
{
    if (matriz.size() >= 2)
    {
        trasponer_DyV(matriz,matriz.size(),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,col_inicio + tam / 2,col_inicio + tam);
    trasponer_DyV(matriz,fil_inicio + tam,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;
}

谢谢!

lxg1238 回答:征服征服者始终可以获得更好的性能吗?

第一个版本正在做更多工作-将片段原位转置,然后将其交换到正确的位置。

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

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

尽管将其并行化(在CPU级别)也将无济于事,因为矩阵转置是完全受DRAM约束的操作。

,

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

恕我直言,如果出现以下情况,您将使用分治法:

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

  2. 该功能的可读性得到了改善(从而增强了可维护性),或者

  3. 从概念上讲,高级算法可以划分为较小的,可能可重用的函数。

本文链接:https://www.f2er.com/2540179.html

大家都在问