【问题标题】:openmp parallel recursive function in cc中的openmp并行递归函数
【发布时间】:2018-06-14 02:58:22
【问题描述】:

如何使用 openMP 并行化以下递归?因为我的代码有问题,可以通过这种方式解决。我从以下站点获得此代码:https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/

代码:

// C program to print all permutations with duplicates allowed
#include <stdio.h>
#include <string.h>

/* Function to swap values at two pointers */
void swap(char *x, char *y)
{
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

/* Function to print permutations of string
This function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. */
void permute(char *a, int l, int r)
{
   int i;
   if (l == r)
     printf("%s\n", a);
   else
   {
       for (i = l; i <= r; i++)
       {
          swap((a+l), (a+i));
          permute(a, l+1, r);
          swap((a+l), (a+i)); //backtrack
       }
   }
}

/* Driver program to test above functions */
int main()
{
    char str[] = "ABC";
    int n = strlen(str);
    permute(str, 0, n-1);
    return 0;
}

【问题讨论】:

  • 如果您根据一些 openmp 教程尝试并行化循环的方法,会无意中发生什么?你尝试了哪些方法?他们以何种方式失败了?你读过嵌套并行化吗?
  • 我看到的教程,不要那样锁定循环,我尝试并行化置换函数,但是,它总是只使用线程 0 进行递归,并且没有在线程之间拆分任务。不得不说我是编程初学者,不知道嵌套并行是怎么工作的。
  • 请展示您如何“尝试并行化置换函数”并解释结果/行为如何令人不满意。尽量避免只要求代码做你想做的事情的印象。
  • 我试过下面的表格。我不知道使用 openmp 来并行化这种递归的策略。我不想要一个现成的代码,只是一个并行化的策略,因为我无法将递归分成两部分。 #pragma omp parallel num_threads(2){permute()str, 0, n-1);}
  • 请编辑您的问题以添加有用的信息。请拨打tour。请阅读How to Ask

标签: c recursion openmp permutation


【解决方案1】:

我至少可以想到两种方法。一种是对permute函数进行并行化,另一种是对rank进行并行化。

此答案使用第二种方法。对于n = strlen(str),排列数(又名排名)是n!。例如。对于str = "ABCD",等级数为24。这是一种在排名上执行此操作的方法(基于this paper):

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define SWAP(a,b) do{t=(a);(a)=(b);(b)=t;}while(0)

void get_permutation(int rank, int n, char *vec) {
    int t, q, r;
    if (n < 1) return;
    q = rank / n;
    r = rank % n;
    SWAP(vec[r], vec[n-1]);
    get_permutation(q, n-1, vec);
}

int main(int argc, char *argv[]) {
  char a[5] = "ABCD", t[5];

  #pragma omp parallel for private(t) schedule(dynamic)
  for (int r = 0; r < 24; ++r) {
    strcpy(t, a);
    get_permutation(r, 4, t);
    #pragma omp critical
    printf("%3d: %s\n", r, t);
  }
}

只要get_permutation 比输出慢(在本例中为printf),此方法应该会在性能上取胜。对于足够大的字符串长度,这将是正确的。

我系统上的输出是

  3: BCAD
  6: DABC
  7: CABD
  9: DACB
  8: BDCA
 10: BADC
 11: BACD
 13: CDAB
 14: DBAC
 15: CBAD
 16: DCBA
  1: DCAB
 17: ACDB
 19: ACBD
 20: DBCA
 21: ADCB
 22: ABDC
 23: ABCD
 12: CBDA
  0: BCDA
 18: ADBC
  4: CDBA
  2: BDAC
  5: CADB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 2023-03-29
    • 2011-01-17
    • 2013-04-21
    相关资源
    最近更新 更多