线程如何在OpenMP中使用具有全局范围的不同变量值?

时间:2015-10-14 13:45:08

标签: c multithreading openmp

我的C程序中的各种函数都使用了很少的全局变量。我并行使用OpenMP个线程。每个线程都会调用这些函数为这些全局变量分配不同的值。除threadprivate之外还有其他选择吗?我不清楚如何使用copyin条款。 示例代码如下:

int main (void) {
     int low=5,high=0;
     ----
     func1(int *k) { do something with low,high and set value for k}
     func2(int *k) { do something with low,high and set value for k}
     func3(int *k) { do something with low,high and set value for k}
     ----
     int i;
     int *arr= malloc(CONSTANT1*sizeof(int));
     #pragma omp parallel num_threads(numberOfThreads) threadprivate(low,high) private(i) shared(arr)
     {
     #pragma omp for
     for(i=0;i<CONSTANT1;i++) {
         low=low+CONSTANT2*i;
         high=low+CONSTANT2;
         func1(&arr[i]);
         func2(&arr[i]);
         func3(&arr[i]);
         ----
     }
     }
}

或者我应该使用private(low,high)并一次又一次地将它们传递给每个函数? 请指教。

1 个答案:

答案 0 :(得分:1)

您的代码段非常模糊,但似乎有些错误。当您提出问题时,我们假设您有以下几点:

int low=5, high=10;
#pragma omp threadprivate(low, high)

func1(int *k) { do something with low,high and set value for k}
func2(int *k) { do something with low,high and set value for k}
func3(int *k) { do something with low,high and set value for k}

[...]

int main (void) {
    [...]
    int i;
    int *arr= malloc(CONSTANT1*sizeof(int));
    #pragma omp parallel num_threads(numberOfThreads) private(i)
    {
        #pragma omp for
        for (i=0; i<CONSTANT1; i++) {
            low = low + CONSTANT2 * i;
            high = low + CONSTANT2;
            func1(&arr[i]);
            func2(&arr[i]);
            func3(&arr[i]);
            [...]
        }
    }
}

然后,尽管使用threadprivate会使代码生效,但由于low = low + CONSTANT2 * i;,您在此处遇到问题。此行取决于low的先前值,因此不适合并行化,因为顺序很重要。但是,如果您更改代码如下:

        int lowinit = low;
        #pragma omp for
        for (i=0; i<CONSTANT1; i++) {
            low = lowinit + CONSTANT2 * i*(i+1)/2;

然后您的代码变得正确(前提是您的函数不会在内部更改low。)

就性能而言,我不确定highlow的全局与参数方面会产生多大影响。但是,我很清楚,将它们作为参数传递而不是全局变量使代码更清晰,更不容易出错。

最后,如果highlow的值在退出并行循环或区域时具有任何重要性,请注意这是将保留的主线程的值,这可能与他们没有OpenMP时的情况有所不同。在这种情况下,您可以在必要时将这些行添加到代码中以确保正确性:

        low = lowinit + CONSTANT2 * (CONSTANT1-1)*CONSTANT1/2;
        high = low + CONSTANT2;