Как ускорить шейкерную сортировку с помощью omp?

Каким образом можно ускорить шейкерную сортировку большого массива (100k).

Обязательное условие: с помощью OMP.

В моём случае лучший(при этом правильный) результат показали 8 потоков.

Я только начинаю разбираться в omp, поэтому принимаются любые советы, идеи, предложения

#include <iostream>
#include <ctime>
#include <fstream>
#include <omp.h> 
#include <time.h>



using namespace std;

#define N 100000

int main()
{

    srand(time(0));
    int A[N], left = 0, right = N - 1, i, n;
    double start, end;

    for (int j = 0; j < N; j++)
    {
        A[j] = rand() % 20 + 1;
    }
    #pragma omp parallel num_threads(8)
    {

        start = omp_get_wtime();

        while (left < right)
        {
            for (int i = left; i < right; i++)
            {
                if (A[i] > A[i + 1])
                    swap(A[i], A[i + 1]);
            }

            right--;

            for (int i = right; i > left; i--)
            {
                if (A[i - 1] > A[i])
                    swap(A[i], A[i - 1]);
            }

            left++;
        }

        end = omp_get_wtime();
    }

    for (int q = 0; q < N; q++)
        printf("%d ", A[q]);

    printf("\nWork took %f seconds\n", end - start);
   }


// results:
// 10k in 0,45 sec
// 100k in 11 sec

Ответы (1 шт):

Автор решения: Chorkov
  1. исправьте алгоритм, так чтобы он отсекал уже отсортированные концы. Это обязательная часть шейкера. Сравните свой код с кодом wiki.
  2. выделите код в отдельную функцию, так чтобы можно было передать указатель + размер + шаг между элементами.
  3. параллельно сортируете отдельные выборки (каждый 8-й элемент, начиная с 0-го, с 1-го, ... ), запуская функцию из (п. 2).
  4. параллельно сортируете кусочки (1/8) массива.
  5. в главном потоке применяете сортировку ко всему массиву (не распараллеливая).

Ускорение, получится за счет того, что к финальному шагу (п.5) массив "в основном", отсортирован. т.е. предется сделать гораздо меньше swap-ов, а за счет (п.1) гораздо меньше циклов верхнего уровня.

Это, конечно, уже не шейкер, но хоть что-то, на него похожее. Правда, теряем стабильность, исходного алгоритма. Если обязательно сохранять стабильность, то исключите п.3 (потеряете в производительности).

→ Ссылка