通过(c ++)openmp在不同线程之间共享信息

时间:2012-01-04 10:06:57

标签: c++ multithreading openmp race-condition

我对并行编程比较陌生,想要通过openmp在c ++中完成以下任务。

我有一些(比方说4)相对复杂的对象/计算要做。所有这些都是相似的,但是太复杂而无法并行化它们(因此它们是串行的)。所以我的想法是为每个使用不同的线程/ cpu,这意味着我想将计算分散到我的核心上。虽然在这种情况下这可能不是并行性最有效的用法,但它可能是最容易实现的(因为每次计算都很复杂)。

虽然这可以通过

工作
#pragma omp parallel
{
    #pragma omp for
    for(int i = 0; i < 4; i++)
    {
       obj[i].calculate();    
    }
}

我想在这些对象之间交换更多信息,例如整数(或更复杂的对象)“a”应该在每次计算中被修改(虽然我无法预测何时和多久,但特别是大多数时候一次)。如果它被修改,则信息也需要合并到彼此的计算中。虽然信息的具体交换(再次)相对复杂,但这也是通过“计算”方法(隐式地)完成的。一般来说,这应该如上所示,附加整数“a”,由所有计算方法写入和读取:

int a;
#pragma omp parallel
{
   #pragma omp for
   for(int i = 0; i < 4; i++)
   {
       obj[i].calculate();    
   }
}

所以我的问题是,如何防止“a”上的“数据竞争”?这意味着我如何生成一个对象,每次只能通过一个线程访问,而不需要在“计算”方法本身中详细说明? openmp是否提供此功能,如果没有,哪个库可以提供?

提前致以最诚挚的问候和谢意!

2 个答案:

答案 0 :(得分:1)

根据您的描述判断,当每个线程都必须等待a的更新信息时,我不确定并行执行是否会对您有所帮助。

无论如何,您可以使用flushatomiccritical指令更新没有竞争条件的变量。最佳选择在很大程度上取决于哪些线程必须更新a或更新a

critical:所有线程一次执行代码

atomic:内存受多重写保护,内部由critical

取代

flush:更新共享变量,由critical

隐式调用

最后,barrier确保所有线程都已达到代码中的相同点。

  

我想在这些对象之间交换更多信息   例如,应修改整数(或更复杂的对象)“a”   在每次计算期间(虽然我无法预测何时和多久,   但特别是大多数一次)。

这句话有点令人恼火,因为您应该知道何时需要更新的a。执行此操作时,您需要在所有线程中都有一个屏障,在关键部分更新a并继续并行执行。那么有多少线程更新a?主线程还是所有主线程?

如果只有一个线程需要更新a,则另一个选项是single指令。它的代码只能由一个具有隐式屏障的线程执行,并在执行后执行隐式刷新。这些是将复杂对象a正确更新到所有线程的一般选项。祝你好运。

答案 1 :(得分:0)

当然,您意识到方法calculate无法访问您发布的代码中的变量a。如果你想这样工作,你可以内联编写计算函数,并在修改a时使用临界区:

int a;
#pragma omp parallel
{
   #pragma omp for
   for(int i = 0; i < 4; i++)
   {
       // code of calculate
       #pragma omp critical
       {
           // modify a
       }
       // other code
   }
}