Openacc: как сделать сортировку вставками более параллельной

Не могли бы вы предложить, как я могу сделать openacc более параллельным. Я делаю сортировку слиянием с сортировкой вставками. Должен ли я использовать «цикл» или «для» для использования цикла. Также для сортировки вставками она должна быть ядерной или параллельной.

#include <stdlib.h>
#include<stdio.h>
#include <time.h>
#include <openacc.h>
#define THR 1000

//Insertion sort
void isort (int *a, int left, int mid, int right) {

int i,j;
# pragma acc kernels
{
# pragma acc parallel loop num_gangs (1024)
for ( i = mid; i <= right; i++) {
    for ( j = i - 1; j >= 0; j--) {
        if (a[i] < a [j]) {
            int temp = a[j];
            a[j] = a[i];
            a[i] = temp;
            i--;
        }
    }
}
}
}
void merge(int a[], int left, int right,int left_half[], int right_half[])
{
int i, j, k;
int mid = (left + right + 1) / 2;

i = j = 0;
k = left;

while (i < mid - left && j <= right - mid) {
    if (left_half[i] < right_half[j]) {
        a[k] = left_half[i];
        ++i;
    } else {
        a[k] = right_half[j];
        ++j;
    }

    ++k;
   }

  // Copying any leftover elements
  #pragma acc data copy(a, right_half)
  while (j <= right - mid) {
        a[k++] = right_half[j++];//copy remaining elements of the first half

    }
   #pragma acc data copy(a, left_half)
   while (i < mid - left) {
        a[k++] = left_half[i++]; //copy remaining elements of the second list
    }
   }

  void mergeSort(int a[], int left, int right)
{
if (left < right) {
    int mid = (left + right + 1) / 2;
    int left_half[mid - left];
    int right_half[right - mid + 1];
    int i;
   # pragma acc kernels
   {
    // Copying elements
    # pragma acc parallel loop shared (left_half, a)
    for (i = left; i < mid; ++i) {
        left_half[i - left] = a[i];
    }

    // Copying elements
    # pragma acc parallel loop shared (right_half, a)
    for (i = mid; i <= right; ++i) {
        right_half[i - mid] = a[i];
    }
  }
    // Recursive call
    mergeSort(left_half, 0, mid - left - 1);
    mergeSort(right_half, 0, right - mid);
    // Merge the two partitions
    if ((right - left) > THR){
        merge(a, left, right, left_half, right_half);
    } else {
        isort(a, left,mid, right);
    }
}
}


  int main()
   {
int i, n, *a,c;

printf("Enter the number of elements\n");
scanf("%d",&n);      
a = (int *)acc_malloc(sizeof(int) * n);  
srand(time(0));
for(i=0;i<n;i++){
   a[i]=rand()%1000;
}
printf("\nThe unsorted a is:");
printf("\n");
for(i=0;i<n;i++)
    printf("%d  ",a[i]);;

    mergeSort(a, 0, n-1);
printf("\nSorted a:");
printf("\n");
for(i=0;i<n;i++)
    printf("%d  ",a[i]);
printf("\n");
 }  

person pragya sharma    schedule 16.04.2017    source источник
comment
Мы не улучшаем мой код сайта.   -  person too honest for this site    schedule 16.04.2017
comment
Спасибо за грубый ответ. Я искал некоторую помощь и руководство, которое я также думаю, что этот сайт не предоставляет.   -  person pragya sharma    schedule 16.04.2017
comment
Кто грубит? Человек, задающий вопрос не по теме, или тот, кто говорит ему, что да? Но не стесняйтесь обижаться просто потому, что вам говорят, что вы не правы.   -  person too honest for this site    schedule 16.04.2017
comment
Я не заходил на этот сайт для болтовни, я хотел помочь, и кажется, что люди не заинтересованы даже в том, чтобы направлять меня, где я делаю неправильно, я не просил никого писать для меня весь код.   -  person pragya sharma    schedule 16.04.2017
comment
Интересно, что бы вы сделали, если бы я пришел к вам домой/квартиру/и т. д., сел на ваш стол и громко потребовал, чтобы меня накормили.   -  person too honest for this site    schedule 16.04.2017
comment
Спасибо за комментарий, мне нужно найти, как сделать мою программу более эффективной, поэтому у меня не так много времени, как у вас. Еще раз спасибо за вопрос.   -  person pragya sharma    schedule 16.04.2017


Ответы (1)


Я не знаю синтаксиса openacc. Что касается синтаксиса openmp, если у вас есть большие массивы для цикла, вы даже можете запускать каждый цикл цикла for параллельно, в то время как оба циклы for выполняются параллельно. Взгляните на эту link1, ссылка2. Я не знаю, вы имели в виду то же самое, написав # pragma acc parallel loop above for loops, или если у вас есть что-то подобное в openacc, вы можете добавить это.

И вы можете запустить обе сортировки слиянием параллельно, что-то вроде этого.

# pragma acc kernels
   {
     # pragma acc parallel{mergeSort(left_half, 0, mid - left - 1);}
     # pragma acc parallel{mergeSort(right_half, 0, right - mid);}
   }
person Aerron    schedule 16.04.2017
comment
Большое спасибо за ваше предложение, я постараюсь добавить обе вещи, которые вы упомянули, и, надеюсь, это сделает код более эффективным. :) - person pragya sharma; 16.04.2017
comment
Значит ли это, что цикл for работает параллельно # pragma acc parallel loop shared , как описано здесь? - person Aerron; 16.04.2017
comment
Да, это улучшило время параллельного выполнения. - person pragya sharma; 16.04.2017
comment
Я спрашивал про цикл for. Добавьте параллель, только если массив достаточно велик, иначе не добавляйте. - person Aerron; 16.04.2017
comment
На самом деле я использую большой размер массива, поэтому мне нужно было добавить параллель. - person pragya sharma; 16.04.2017
comment
Что ж, главное в сортировке слиянием — добавить параллель для двух сортировок слиянием, а затем, если итераций достаточно много, мы можем добавить параллель для. В Parallel for начальное разделение работы, настройка рабочих потоков и вызов функции/операции для каждой итерации требуют определенных затрат, которые могут привести к снижению производительности вместо ее улучшения. - person Aerron; 16.04.2017
comment
Это означает, что мы не должны использовать параллель в случае небольшого количества элементов в массиве? Это может снизить производительность? Кстати, спасибо, вы действительно хорошо объяснили. :) - person pragya sharma; 16.04.2017
comment
Да, используйте только тогда, когда каждая итерация занимает много времени, так как она может иметь много функторов и требует времени, или когда у нас было много циклов. Ну, я тоже новичок, просто недавно я сделал небольшой проект решения судоку по параллельному программированию с использованием OpenMP. - person Aerron; 17.04.2017
comment
большое спасибо вы действительно очень помогли. - person pragya sharma; 17.04.2017
comment
Лол, за что ты меня так благодаришь✌️ Все хорошо, приятель. - person Aerron; 17.04.2017
comment
На самом деле я также новичок в openacc, и мне нужно представить отчеты для моего университетского проекта, поэтому я вошел на этот сайт, и мой первый опыт, возможно, вы уже читали в предыдущих комментариях. Так что я должен поблагодарить вас за хороший ответ и помощь мне. :) - person pragya sharma; 17.04.2017
comment
Значит, вы имеете в виду, что написание параллельной сортировки слиянием — это проект для вас? - person Aerron; 17.04.2017
comment
Да, это проект, и мы должны отчитаться об OpenAcc и Cuda. - person pragya sharma; 17.04.2017
comment
Хорошо, было бы хорошо, если бы вы выбрали что-то нетривиальное, например, какую-нибудь многопользовательскую параллельную игру или параллельный загрузчик. В любом случае :) продолжайте. - person Aerron; 17.04.2017
comment
Да, но все в порядке. Спасибо. :) - person pragya sharma; 17.04.2017
comment
Лол, я только начал отвечать здесь и получил много уведомлений о переполнении стека с комментариями и предложениями. Яааа спасибо за поддержку :) - person Aerron; 17.04.2017