OpenMP全局私有变量

时间:2018-12-04 22:18:48

标签: c function task openmp

我确实对我的并行C代码有疑问。在不更改bar()的返回类型或向bar()添加参数的情况下,我不知道如何在{{1}之后递归调用foo()的情况下让*number知道bar() }。

第二,我想知道是否调用了bar()之后的注释,以解释任务的最后一个子句? 为了便于记录,在这种情况下,rmaxIndex(A)lminIndex(A)A是整数数组,并且所有3个都是foo()

int *number;
#pragma omp threadprivate(number)

void bar(...) 
{ 
    [...] 
    *number = i + 1; 
}

void foo(...)
{
    if(...)
    {
        bar(...);
        // no more tasks for arrays (< 100 elements)?
        #pragma omp task final(r - l <= 100)
            foo(*number - 1);
        #pragma omp task final(r - l <= 100)
            foo(*number + 1);
    }
}

int main(...)
{
    [...]
    #pragma omp parallel
        #pragma omp single
            foo(...);
    #pragma omp taskwait
    [...]
}

1 个答案:

答案 0 :(得分:0)

您正试图将数字从一个函数(barfind_pivot)传递给其调用方(fooquicksort)。

使用全局变量是一种不好的模式。更改不允许您执行的测试。尝试解决该问题,将使您难以阅读,无法维护,并且代码非常复杂。实际上,它使它变得无用的复杂,以至于当替代方案非常简单时,您甚至都无法弄清楚如何编写它。

比较:

int find_pivot(int *arr, int low, int high)
{
    return ...;
}

void quicksort(int *arr, int low, int high)
{
    ...
    int pivot_index = find_pivot(arr, low, high);
    quicksort(arr, low, pivot_index - 1);
    quicksort(arr, pivot_index + 1, high);
}

或使用指针(通常是如果您有多个值或一个复数值返回):

void find_pivot(int *arr, int low, int high, int *pivot_index)
{
    *pivot_index = ...;
}

void quicksort(int *arr, int low, int high)
{
    ...
    int pivot_index = -1;
    find_pivot(arr, low, high, &pivot_index);
    quicksort(arr, low, pivot_index - 1);
    quicksort(arr, pivot_index + 1, high);
}

以下内容(错误!)与您所写的内容很接近:

int pivot_index;

void find_pivot(int *arr, int low, int high)
{
    pivot_index = ...;
}

void quicksort(int *arr, int low, int high)
{
    ...
    find_pivot(arr, low, high);
    // What happens if two tasks call pivot_index simultaneously?
    // Which value will you get for quicksort? No way of knowing!
    quicksort(arr, low, pivot_index - 1);
    // pivot_index has changed value due to recursive quicksort() ! The next call is wrong!
    quicksort(arr, pivot_index + 1, high);
}

不仅可读性较差(例如,在阅读quicksort时,pivot_index是从哪里来的?),而且还需要修复(不要使用它,这太糟糕了!):

// can be set from several threads simultaneously
int pivot_index;
#pragma omp threadprivate(pivot_index)

void find_pivot(int *arr, int low, int high)
{
    pivot_index = ...;
}

void quicksort(int *arr, int low, int high)
{
    ...
    find_pivot(arr, low, high);
    // save value to protect from recursive calls
    int my_pivot_index = pivot_index;
    quicksort(arr, low, my_pivot_index - 1);
    quicksort(arr, my_pivot_index + 1, high);
}