- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我在一个对象中打包了一些资源,然后根据这些资源进行一些计算。我通常做的是初始化并行区域外的对象,然后使用firstprivte关键字
int main()
{
// initialize Widget objs
Widget Widobj{params1,params2,params3...};
#pragma omp parallel for firstprivate(Widobj)
for (int i=0; i< N; ++i)
{
// computation based on resources in Widobj
}
}
而且我认为在这种情况下,每个线程都会独立处理 Widobj 中的资源,并且我想每个线程都会有一个 Widobj 的拷贝(可能是一个深层拷贝,对吗?)。现在我对另一个关键字 threadprivate 感到困惑,threadprivate 在这种情况下如何工作?在我看来它们非常相似
最佳答案
当对象声明为firstprivate
时,复制构造函数被调用,而当使用private
时,默认构造函数被调用。我们将在下面解决 threadprivate
。证明(英特尔 C++ 15.0):
#include <iostream>
#include <omp.h>
class myclass {
int _n;
public:
myclass(int n) : _n(n) { std::cout << "int c'tor\n"; }
myclass() : _n(0) { std::cout << "def c'tor\n"; }
myclass(const myclass & other) : _n(other._n)
{ std::cout << "copy c'tor\n"; }
~myclass() { std::cout << "bye bye\n"; }
void print() { std::cout << _n << "\n"; }
void add(int t) { _n += t; }
};
myclass globalClass;
#pragma omp threadprivate (globalClass)
int main(int argc, char* argv[])
{
std::cout << "\nBegninning main()\n";
myclass inst(17);
std::cout << "\nEntering parallel region #0 (using firstprivate)\n";
#pragma omp parallel firstprivate(inst)
{
std::cout << "Hi\n";
}
std::cout << "\nEntering parallel region #1 (using private)\n";
#pragma omp parallel private(inst)
{
std::cout << "Hi\n";
}
std::cout << "\nEntering parallel region #2 (printing the value of "
"the global instance(s) and adding the thread number)\n";
#pragma omp parallel
{
globalClass.print();
globalClass.add(omp_get_thread_num());
}
std::cout << "\nEntering parallel region #3 (printing the global instance(s))\n";
#pragma omp parallel
{
globalClass.print();
}
std::cout << "\nAbout to leave main()\n";
return 0;
}
给予
def c'tor
Begninning main()
int c'torEntering parallel region #0 (using firstprivate)
copy c'tor
Hi
bye bye
copy c'tor
Hi
bye bye
copy c'tor
Hi
bye bye
copy c'tor
Hi
bye byeEntering parallel region #1 (using private)
def c'tor
Hi
bye bye
def c'tor
Hi
bye bye
def c'tor
Hi
bye bye
def c'tor
Hi
bye byeEntering parallel region #2 (printing the value of the global instance(s) and adding the thread number)
def c'tor
0
def c'tor
0
def c'tor
0
0Entering parallel region #3 (printing the global instance(s))
0
1
2
3About to leave main()
bye bye
bye bye
如果复制构造函数执行深拷贝(如果您必须自己编写它应该这样做,如果您不这样做并且有动态分配的数据则默认执行),那么您将获得对象的深拷贝。这与不使用现有对象初始化私有(private)拷贝的 private
相反。
threadprivate
的工作方式完全不同。首先,它仅适用于全局或静态变量。更重要的是,它本身就是一个指令,不支持任何其他子句。您在某处编写了 threadprivate
pragma 行,然后在并行 block 之前编写了 #pragma omp parallel
。还有其他差异(对象在内存中的存储位置等),但这是一个好的开始。
让我们分析一下上面的输出。首先,请注意,在进入区域#2 时,调用默认构造函数创建线程专用的新全局变量。这是因为在进入第一个并行区域时,全局变量的并行拷贝尚不存在。
接下来,正如 NoseKnowsAll 认为的最关键的区别,线程私有(private)全局变量在不同的并行区域中是持久的。在区域 #3 中没有构造,我们看到从区域 #2 添加的 OMP 线程数被保留。另请注意,在区域 2 和 3 中没有调用析构函数,而是在离开 main()
之后(由于某种原因只有一个(主)拷贝 - 另一个是 inst
. 这可能是一个错误...)。
这让我们明白了我使用英特尔编译器的原因。 Visual Studio 2013 和 g++(在我的电脑上是 4.6.2,Coliru (g++ v5.2),codingground (g++ v4.9.2))只允许 POD类型(source)。这被列为近十年来的错误,但仍未得到完全解决。给出的 Visual Studio 错误是
error C3057: 'globalClass' : dynamic initialization of 'threadprivate' symbols is not currently supported
而g++给出的错误是
error: 'globalClass' declared 'threadprivate' after first use
英特尔编译器使用类。
还有一点。如果你想复制主线程变量的值,你可以使用 #pragma omp parallel copyin(globalVarName)
.请注意,这不适用于我们上面示例中的类(因此我将其省略)。
来源:OMP tutorial : private , firstprivate , threadprivate
关于c++ - 对 OpenMP 上下文中的 firstprivate 和 threadprivate 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32347008/
底线 如何确保 threadprivate 实例被正确销毁? 背景 回答this question时在 VS2013 中使用英特尔 C++ 15.0 编译器时,我遇到了一个奇怪的问题。当声明一个全局变
我有四个全局变量 extern Vars vars; extern Params params; extern Workspace work; extern Settings settings 我正在
我从 C 调用一段 Fortran 代码,然后再调用一些其他 C 代码。为了调用 C 代码的最后一位,我需要有两个全局指针,分别指向我定义的 EarthModel 结构和 SurveyGeometry
我运行了一个OpenMP程序的例子来测试threadprivate的功能,但结果是意外的和不确定的。 (该程序在VMware中的ubuntu 14.04上运行。) 源码如下所示: int counte
关于 this问题其中一个答案引用了 OpenMP 标准的以下部分: A threadprivate variable with class type must have: an accessible
我不知道如何使结构或对象成为线程私有(private)的,我正在做的事情会产生错误: struct point2d{ int x; int y;
我的程序是这样的: int *array; #pragma omp threadprivate(array1) int main() { array = new int[N];//N is a
我是 OpenMp 世界的新手,遇到了一个错误,我无法修复。原始代码太大了,所以我做了一个小代码来总结问题: 我得到了一个更多维的 std::vector(2d 和 3d),它不应该在线程之间共享。如
Visual Studio 2010 中的 OpenMP 实现似乎有一个严重的错误,不允许将外部变量作为 threadprivate。以下代码将无法编译: 文件.c #include /* Decl
假设我在一个对象中打包了一些资源,然后根据这些资源进行一些计算。我通常做的是初始化并行区域外的对象,然后使用firstprivte关键字 int main() { // initial
考虑以下片段: #include class A { static std::map theMap; #pragma omp threadprivate(theMap) }; std::ma
我正在修改一些旧的 Fortran 代码以使用 OpenMP 指令运行,并且它大量使用了 COMMON 块。我发现多个消息来源说使用 OMP 指令将 COMMON 块声明为 THREADPRIVATE
我是一名优秀的程序员,十分优秀!