openMP 并行部分中的共享变量有些奇怪
Something strange with shared variable in openMP parallel sections
我在openMP
中遇到了一个奇怪的现象,共享货币和打印功能。
我在 C++
和 Fortran
中测试了这个问题。
在 C++ 中:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main (int argc, char *argv[])
{
int i=1;
#pragma omp parallel sections shared(i)
{
#pragma omp section
{while(true){
i = 1;
printf("thread 1: %i\n", i);
}}
#pragma omp section
{while(true){
i = i - 1000;
printf("thread 2: %i\n", i);
}}
}
}
这段代码很简单,预期的结果是这样的:
thread 1: 1
thread 2: -999
thread 1: 1
thread 2: -999
thread 2: -1999
thread 1: 1
但是,我可以得到这个结果:
thread 1: 1
thread 2: -1726999
thread 2: -1727999
thread 2: -1728999
thread 2: -1729999
thread 2: -1730999
thread 2: -1731999
thread 2: -1732999
这很混乱,看起来我没有被分享!我试图评论这一行:
printf("thread 1: %i\n", i);
并得到:
thread 2: 1
thread 2: -999
thread 2: 1
thread 2: 1
thread 2: -999
thread 2: 1
现在看起来不错。
在 Fortan 中:
OpenMP
在 Fortran 中的表现略有不同。
PROGRAM test
implicit none
integer*8 i
i = 1
!$OMP parallel sections shared(i)
!$OMP section
do
i = 1
print *, "thread 1" ,i
!call sleep(1)
end do
!$OMP section
do
i = i-1000
print *, "thread 2" ,i
!call sleep(1)
end do
!$OMP end parallel sections
END PROGRAM
此代码导致与上述相同的问题。但是如果我评论线程1的打印,问题仍然存在。
我必须添加 sleep
子例程作为注释行以获得预期结果。
有人知道原因吗?
另一个问题,一个变量在一个线程中被修改的同时在另一个线程中被读取可以吗?
您正在从多个线程修改共享变量,但没有进行同步。这被称为数据竞争。你的程序的结果是不确定的——任何事情都有可能发生。如果您在一个线程中写入一个变量并在没有同步的情况下从另一个线程读取变量,这同样适用。
有关详细信息,请参阅 the OpenMP 4.0 standard 的第 1.4.1 节。
我在openMP
中遇到了一个奇怪的现象,共享货币和打印功能。
我在 C++
和 Fortran
中测试了这个问题。
在 C++ 中:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main (int argc, char *argv[])
{
int i=1;
#pragma omp parallel sections shared(i)
{
#pragma omp section
{while(true){
i = 1;
printf("thread 1: %i\n", i);
}}
#pragma omp section
{while(true){
i = i - 1000;
printf("thread 2: %i\n", i);
}}
}
}
这段代码很简单,预期的结果是这样的:
thread 1: 1
thread 2: -999
thread 1: 1
thread 2: -999
thread 2: -1999
thread 1: 1
但是,我可以得到这个结果:
thread 1: 1
thread 2: -1726999
thread 2: -1727999
thread 2: -1728999
thread 2: -1729999
thread 2: -1730999
thread 2: -1731999
thread 2: -1732999
这很混乱,看起来我没有被分享!我试图评论这一行:
printf("thread 1: %i\n", i);
并得到:
thread 2: 1
thread 2: -999
thread 2: 1
thread 2: 1
thread 2: -999
thread 2: 1
现在看起来不错。
在 Fortan 中:
OpenMP
在 Fortran 中的表现略有不同。
PROGRAM test
implicit none
integer*8 i
i = 1
!$OMP parallel sections shared(i)
!$OMP section
do
i = 1
print *, "thread 1" ,i
!call sleep(1)
end do
!$OMP section
do
i = i-1000
print *, "thread 2" ,i
!call sleep(1)
end do
!$OMP end parallel sections
END PROGRAM
此代码导致与上述相同的问题。但是如果我评论线程1的打印,问题仍然存在。
我必须添加 sleep
子例程作为注释行以获得预期结果。
有人知道原因吗?
另一个问题,一个变量在一个线程中被修改的同时在另一个线程中被读取可以吗?
您正在从多个线程修改共享变量,但没有进行同步。这被称为数据竞争。你的程序的结果是不确定的——任何事情都有可能发生。如果您在一个线程中写入一个变量并在没有同步的情况下从另一个线程读取变量,这同样适用。
有关详细信息,请参阅 the OpenMP 4.0 standard 的第 1.4.1 节。