C-OpenMP /尝试将递归代码与任务并行化,但工作速度较慢

时间:2017-12-11 06:33:25

标签: c openmp

来自墨西哥的问候!

我面临着并行处理涉及递归的几个代码的任务,在做了一些研究之后,我意识到最好的方法是利用omp的任务。但是,它的运行时似乎比串行对应物大得多。

我知道在这个论坛上已经多次询问过这个问题但是所提议的解决方案似乎都不适合我的情况。

下面我添加我的代码。 infijaParallelSearch()接收BST的头部和要查找的值,如果它在树中,则返回节点。 convertToBST()接收一个排序列表并将其转换为返回头部的二进制搜索树。

typedef struct node
{
    int key;
    struct node *left;
    struct node *right;
} Node;


Node* convertToBST(int* array, int size) {
    if( size == 1)
        return NULL;
    Node* root= (Node*)malloc(sizeof(Node));
    if(root == NULL)
    {
        printf("Error creating a new node.\n");
        exit(0);
    }
    root->key=array[size/2-1];
    root->left=convertToBST(array,size/2);
    root->right=convertToBST(array+size/2,size-size/2);
    return root;
}

Node* infijaParallelSearch(Node* root, int x){
    if( root == NULL)
        return NULL;
    if( root->key == x )
        return root;
    #pragma omp task firstprivate(root)
        infijaParallelSearch(root->left,x);

    infijaParallelSearch(root->right,x);
}

当我使用增加长度的列表运行它以将其运行时与其序列对应物进行比较时,我得到:Runtime results

我正在使用omp_get_wtime()测量时间,我已经尝试了几乎所有内容,从单遍历到多次遍历,似乎没有任何区别。如果代码长度低于并行代码执行得更好的值,我也考虑过将代码串行化,但是在多次运行代码后,该值似乎不存在。

再次感谢您的时间。这是我第一次询问,我希望我不以任何方式模糊。我是初学者,我只是在培养我对编码的热情,所以任何帮助或建议都会非常感激。

PS:我不知道它是否会产生影响但是在下面我添加了用于比较两个代码的运行时间的代码。

    int main(){
    int i,*ptrA,n=10;
    double startTime, normalTime, parallelTime;
    FILE *fPtr;

    fPtr=fopen("statistics.txt","w");
        if(fPtr == NULL){
            printf("File cannot be created");
            exit(0);
        }
    while(n<=100000){
        printf("\nTamaño: %d\t",n);

        ptrA = (int*)calloc(n,sizeof(int));
        if (ptrA == NULL)
        {
            printf("Error 401. Memory not available");
            exit(0);
        }


        for (i=0;i<n;i++){
            ptrA[i]=i+1;
        }
        Node *root=convertToBTS(ptrA,n);

        startTime=omp_get_wtime();
        infijaParallelSearch(root,-1);
        normalTime=omp_get_wtime()-startTime;
        printf("Parallel final Time: %f\t",normalTime);

        for (i=0;i<n;i++){
            ptrA[i]=i+1;
        }

        root=convertToBTS(ptrA,n);

        startTime=omp_get_wtime();
        infijaSearch(root,-1);
        parallelTime=omp_get_wtime()-startTime;
        printf("Normal final Time: %f\n",parallelTime);
        free(ptrA);

        fprintf(fPtr,"%d::%f::%f\n",n,normalTime,parallelTime);

        n+=100;
    }
    fclose(fPtr);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

首先,假设你使搜索并行化的假设会随着数据大小的增加而出现性能提升。 根据您的运行时结果,我们可以得出结论,即使您在序列化版本中提供的阵列大小的总运行时间更快,但与并行版本相比,随着大小的增加,它肯定会变得更糟。

例如,在将数组大小增加近10倍(从100到10000)时,序列化版本的性能会降低50倍。但是并行版本只慢了约40倍(这意味着在并行版本中性能增益更好)。

这使我假设使用足够大的数据集,并行版本将胜过序列化版本。

为什么会这样? 无论你如何选择在这里实现并发,产生新任务(线程)都会产生开销,在你的情况下,它恰好比你要完成的每个工作项目工作要大。