Всегда ли «Разделяй и властвуй» работает лучше?

В настоящее время я тестирую некоторые алгоритмы «разделяй и властвуй» в сравнении с их обычными реализациями. Я новичок в этом, и я не уверен, всегда ли я должен получать лучшую производительность при использовании разделяй и властвуй. Например, я реализовал алгоритм для традиционного переноса матрицы и использования «разделяй и властвуй», но я все равно получаю лучшую производительность, используя первую версию. Возможно ли это, или я упускаю что-то важное?

Вот код, использующий разделяй и властвуй

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;
}

Заранее спасибо!


person Adrisui3    schedule 31.03.2020    source источник
comment
вы не задавали тот же вопрос раньше?   -  person 463035818_is_not_a_number    schedule 01.04.2020
comment
Я сделал, но не добавил код и он был закрыт   -  person Adrisui3    schedule 01.04.2020
comment
Чтобы сравнить производительность двух алгоритмов, нам нужно увидеть код обоих алгоритмов.   -  person Jerry Jeremiah    schedule 01.04.2020


Ответы (2)


Первая версия выполняет больше работы — она перемещает фрагменты на месте, а затем меняет их местами в нужном месте.

Второй вариант переставляет по одному элементу, но уже до конечного места.

Кроме того, в последовательном процессе принцип «разделяй и властвуй» полезен только тогда, когда рабочий набор не помещается в кэш-память L3 (8 МБ или более), что соответствует размеру матрицы >1000*1000.

Хотя его распараллеливание (на уровне ЦП) также не принесет пользы, поскольку транспонирование матрицы — это операция, полностью связанная с DRAM.

person rustyx    schedule 31.03.2020
comment
Что я могу сделать, чтобы оптимизировать первую версию? - person Adrisui3; 01.04.2020
comment
Подумайте, как транспонировать фрагменты попарно за один проход. Рассмотрим диагональную симметрию матрицы. - person rustyx; 01.04.2020
comment
Это заняло некоторое время, но я понял, что вы имели в виду. Большое спасибо, это было действительно полезно! - person Adrisui3; 05.04.2020

Ожидается, что первая функция будет более производительной, поскольку она не выполняет никаких дополнительных вызовов функций, которые не являются бесплатными.

ИМХО, вы бы использовали разделяй и властвуй, если:

  1. Вы можете использовать несколько процессоров параллельно — используя потоки или MPI-подобную среду, или

  2. Читаемость функции улучшается (что приводит к повышению ремонтопригодности), или

  3. Алгоритм более высокого уровня можно концептуально разделить на более мелкие, потенциально повторно используемые функции.

person R Sahu    schedule 31.03.2020
comment
Я знаю всю теорию, но не вижу причин, по которым разделяй и властвуй не работает лучше базового алгоритма :( - person Adrisui3; 01.04.2020