C OpenMP for-loop全局可变问题

C++ OpenMP for-loop global variable problems

本文关键字:问题 全局 OpenMP for-loop      更新时间:2023-10-16

我是OpenMP的新手,并且据我阅读的有关OpenMP 2.0的内容,这是Microsoft Visual Studio 2010,全局变量在并行编程中使用时被认为是麻烦和错误的。我也一直在采用这种感觉,因为我几乎没有发现如何有效地处理全球变量和静态全球变量,或者根本就此。

我有一个运行的代码段,但是由于在并行块中创建的局部变量,所以我没有得到正在寻找的答案。我得到了8个不同的打印量(因为我在PC上有多少个线程),而不是1个答案。我知道这是因为在并行块中创建的局部变量"列表",但是如果我移动"列表"变量并使其成为全局变量,则该代码将不会运行。实际上,代码确实运行,但它永远不会给我回答。这是我想修改以使用全局"列表"变量的示例代码:

#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;

根据MSDN文档,并行子句

定义一个并行区域,该区域将由代码执行 并行多个线程。

并且由于在本节内声明了列表变量,每个线程都会有自己的列表。

另一方面,For Pragma

导致在平行区域内进行循环中完成的工作 划分线程。

因此,50000迭代将在线程之间分配,但每个线程都有其自己的列表。我认为您要做的事情可以通过:

来实现
  1. 在"并行"部分之外获取列表定义。
  2. 保护列表。push_back语句,带有关键部分。

尝试以下操作:

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 ::向量的实现将看起来更干净(因为您不必复制数组)。

某些应用程序是内存绑定的,而不是计算绑定的。底线:检查您是否真的从OpenMP获得了加速。

为什么在这里需要第一个巴格马?(#pragma OMP平行)。我认为这是问题。