我正在测试threadprivate子句如何在openMP中工作。我设置了以下简单的测试用例
#include <iostream>
#include <omp.h>
void func(){
static int some_id = omp_get_thread_num();
#pragma omp threadprivate(some_id)
#pragma omp critical
{
std::cout << "id:" << some_id << std::endl;
std::cout << "in thread " << omp_get_thread_num() << std::endl;
}
}
int main() {
omp_set_num_threads(4);
#pragma omp parallel
func();
}我用gcc7.2编译了这段代码并运行了它
id:1
in thread 1
id:0
in thread 0
id:0
in thread 3
id:0
in thread 2我知道C++标准(至少在C++03标准之后)保证静态变量由一个线程初始化,并且所有其他线程都会被阻塞,直到初始化完成为止。尽管如此,我期望所有线程中的id的本地副本具有相同的值(负责初始化的线程的id )。为什么id在thread#1中不同于其他线程?显然,我的threadprivate心理模型是有缺陷的。你能解释一下这是怎么回事吗?
发布于 2021-07-27 06:22:20
我认为这是实现中的一个缺陷。OpenMP API规范要求每个线程初始化some_id变量:
具有动态初始化器的块作用域线程私有变量的每个副本在其线程第一次遇到其定义时被初始化;如果它的线程没有遇到它的定义,那么它的初始化是未指定的。
(见https://www.openmp.org/spec-html/5.1/openmpsu114.html#x149-1630002.21.2)
GCC 9.3.0在我的机器上有同样的行为:
$ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -O0 -g -fopenmp -o tp tp.cc
$ ./tp
id:0
in thread 0
id:0
in thread 3
id:0
in thread 1
id:0
in thread 2而clang 12则做正确的事情:
$ clang --version
clang version 12.0.0 (/net/home/micha/projects/llvm/llvm-project/clang d28af7c654d8db0b68c175db5ce212d74fb5e9bc)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /net/software/x86_64/clang/12.0.0/bin
$ clang++ -g -O0 -fopenmp -o tp ./tp.cc
$ ./tp
id:2
in thread 2
id:0
in thread 0
id:3
in thread 3
id:1
in thread 1https://stackoverflow.com/questions/68538728
复制相似问题