Openacc:如何使插入排序更加并行[关闭]

Posted

技术标签:

【中文标题】Openacc:如何使插入排序更加并行[关闭]【英文标题】:Openacc: How can I make insertion sort more parallel [closed] 【发布时间】:2017-04-16 08:39:00 【问题描述】:

您能否建议我如何使 openacc 更加并行。我正在使用插入排序进行合并排序。我应该使用“循环”还是“for”来使用循环。对于插入排序,它应该是内核还是并行。

#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");
   

【问题讨论】:

我们不是“改进我的代码”网站。 感谢粗鲁的回复。我正在寻找一些帮助和指导,我认为这个网站也没有提供。 谁在粗鲁?发布离题问题的人还是告诉他他这样做的人?但是,只要被告知你错了,你就会感到被冒犯。 我没有登录这个网站进行闲聊,我需要帮助,似乎人们甚至不感兴趣甚至指导我哪里做错了,我没有要求任何人编写完整的代码我。 感谢您的评论,我必须找到如何让我的程序更有效率,所以我没有你那么多时间。再次感谢您的好奇。 【参考方案1】:

我不知道openacc的语法。 对于 openmp 语法,如果您有 更大 数组要循环,您甚至可以并行运行 for 循环的每个循环,同时两个 for 循环并行运行。看看这个link1,link2。我不知道你写# pragma acc parallel loop above for loops是不是这个意思,或者如果你在openacc中有类似的东西,你可以添加它。

你可以同时运行两个归并排序,像这样。

# pragma acc kernels
   
     # pragma acc parallelmergeSort(left_half, 0, mid - left - 1);
     # pragma acc parallelmergeSort(right_half, 0, right - mid);
   

【讨论】:

非常感谢您的建议,我将尝试添加您提到的内容,希望它会使代码更高效。 :) 这是否意味着 for 循环在这里并行运行 # pragma acc parallel loop shared 和 described 是的,它提高了并行执行时间。 我在询问 for 循环。仅当数组足够大时才添加并行,否则不要添加。 实际上我使用的是大数组,所以我需要添加并行。

以上是关于Openacc:如何使插入排序更加并行[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何使链表排序?

无法并行化OpenACC循环

我可以使用 OpenACC 并行化调用某些函数的大代码吗?

如何通过Java代码在PDF中插入替换或删除图像?

OpenACC + MPI Fortran 程序入门

如何使应用程序永远不会关闭并每小时执行一次程序?