我是OpenMP的新手,从我读过的关于OpenMP 2.0(Microsoft Visual Studio 2010标准版)的内容来看,全局变量在并行编程中使用时会被认为很麻烦且容易出错。我也一直在采用这种感觉,因为我发现很少有关于如何有效地处理全局变量和静态全局变量,或根本没有。
我有这段代码运行,但由于在并行块中创建的局部变量,我没有得到我正在寻找的答案。我得到8种不同的打印输出(因为我的PC上有多少个线程)而不是1个答案。我知道这是因为并行块中创建的局部变量“list”,但如果我移动“list”变量并使其成为全局变量,则此代码将不会运行。实际上代码确实运行但它从来没有给我回答。这是我想要修改以使用全局“列表”变量的示例代码:
#pragma omp parallel
{
vector<int> list;
#pragma omp for
for(int i = 0; i < 50000; i++)
{
list.push_back(i);
}
cout << list.size() << endl;
}
输出:
6250
6250
6250
6250
6250
6250
6250
6250
他们加起来达到50000,但我没有得到50000的答案,而是分开了。
解决方案:
vector<int> list;
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < 50000; i++)
{
cout << i << endl;
#pragma omp critical
{
list.push_back(i);
}
}
}
cout << list.size() << endl;
答案 0 :(得分:1)
根据MSDN Documentation并行条款
定义一个并行区域,这是将由其执行的代码 多个线程并行。
由于list变量是在此部分内声明的,因此每个线程都有自己的列表。
另一方面,for pragma
使并行区域内的for循环完成工作 在线程之间划分。
因此,50000次迭代将在线程之间进行分割,但每个线程都有自己的列表。 我认为你要做的事情可以通过以下方式实现:
试试这个:
vector<int> list;
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < 50000; i++)
{
#pragma omp critical
{
list.push_back(i);
}
}
}
cout << list.size() << endl;
在这种情况下,我认为你不应该从OpenMP获得任何加速,因为会有关键部分的争用。更快的解决方案(如果你不关心元素的顺序)将是每个线程都有自己的列表,并在循环结束后合并这些列表。在这种情况下,使用std :: list而不是std :: vector的实现看起来更干净(因为你不必复制数组)。
某些应用程序受内存限制,不受计算限制。底线:检查您是否真的从OpenMP获得了加速。
答案 1 :(得分:0)
为什么你需要第一个pragma? (#pragma omp parallel)。我认为这就是问题所在。