简体   繁体   English

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

[英]How can threads use different values of variables with global scope in OpenMP?

I have few global variables which are being used by various functions in the C program. 我很少有C程序中的各种函数正在使用的全局变量。 I am using OpenMP threads in parallel. 我正在并行使用OpenMP线程。 Each thread will call these functions assigning different values to these global variables. 每个线程将调用这些函数,为这些全局变量分配不同的值。 Is there any other alternative to threadprivate ? 还有其他替代threadprivate吗? It's not clear to me how to use copyin clause. 我不清楚如何使用copyin子句。 The sample code is like this: 示例代码如下:

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]);
         ----
     }
     }
}

Or shall I use private(low,high) and pass them again and again to each function? 还是我应该使用private(low,high)并将它们一次又一次地传递给每个函数? Please advise. 请指教。

Your code snippet is quite obscure but seem buggy. 您的代码段相当模糊,但似乎有问题。 Let's assume you had the following in mind when you asked your question: 假设您提出问题时谨记以下几点:

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]);
            [...]
        }
    }
}

Then, although the use of threadprivate makes the code valid, you have a problem here because of low = low + CONSTANT2 * i; 然后,尽管使用threadprivate使代码有效,但由于low = low + CONSTANT2 * i; ,您在这里遇到了问题low = low + CONSTANT2 * i; . This line depends on the previous value of low and is therefore not suited for parallelisation since the order matters. 这条线取决于先前的low ,因此不适合并行化,因为顺序很重要。 However, if you change your code like this: 但是,如果您像这样更改代码:

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

Then your code becomes correct (provided your functions do not change low internally). 然后,您的代码将变为正确的(前提是您的函数在内部不会low )。

In term of performance, I'm not sure the global versus parameter aspect of high and low will make much of a difference. 在性能方面,我不知道在全球与参数方面的highlow将使多大的差别。 However, it is clear to me that having them passed as parameters rather than global variable makes the code much cleaner and less error prone. 但是,对我来说很明显,将它们作为参数而不是全局变量传递可以使代码更简洁,更不会出错。

Finally, if the values of high and low have any sort of importance upon exit of the parallel loop or region, be aware that this is the ones of the master thread that will be kept, which are likely to be different from the ones they would have had without OpenMP. 最后,如果在并行循环或区域退出时, highlow的值具有某种重要性,请注意,这是将要保留的主线程,可能与它们将要保留的主线程不同。没有OpenMP。 In such case, you can add these lines to your code where necessary to ensure correctness: 在这种情况下,可以在必要时将以下行添加到代码中以确保正确性:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM