我的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)
并一次又一次地将它们传递给每个函数?
请指教。
答案 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
。)
就性能而言,我不确定high
和low
的全局与参数方面会产生多大影响。但是,我很清楚,将它们作为参数传递而不是全局变量使代码更清晰,更不容易出错。
最后,如果high
和low
的值在退出并行循环或区域时具有任何重要性,请注意这是将保留的主线程的值,这可能与他们没有OpenMP时的情况有所不同。在这种情况下,您可以在必要时将这些行添加到代码中以确保正确性:
low = lowinit + CONSTANT2 * (CONSTANT1-1)*CONSTANT1/2;
high = low + CONSTANT2;