如何使用openmp来并行化数组元素的移动

时间:2016-09-08 00:28:12

标签: arrays algorithm parallel-processing openmp

如果pArray非常大,代码片段在我的程序中最耗时。 last是这个数组的结束位置的变量,Idx是数组特定位置的变量,所以我想要的是将Idx中的部分数组元素向后移动1.

for(long i = last; i >= Idx; i--)
{
    pArray[i] = pArray[i-1];
}

我只是尝试使用parallel来并行化这个,但它肯定无法工作。谁能告诉我这个代码是否可以与openmp并行化?如果是的话,如何编码呢?感谢。

#pragma omp parallel for
for(long i = last; i >= Idx; i--)
{
    pArray[i] = pArray[i-1];
}

3 个答案:

答案 0 :(得分:2)

您遇到的主要问题是您的代码具有循环携带的依赖关系,即迭代之间存在依赖关系。

所以你的代码是:

for(long i = last; i >= Idx; i--)
{
  pArray[i] = pArray[i-1];
}

现在,让我们说last = 4Idx=1。你会有类似的东西:

  iteration 0: pArray[4] = pArray[3];
  iteration 1: pArray[3] = pArray[2];
  iteration 2: pArray[2] = pArray[1];
  iteration 3: pArray[1] = pArray[0];

如果将此并行化为四个线程(让我们静态地说),并且线程0被指定为迭代0,线程1被指定为迭代1,依此类推,您将得到不正确的结果,具体取决于首先执行的线程。如果线程0在线程1之前执行,则线程0将使用pArray[3]的旧值,而如果线程0在线程1之后执行,则线程0将使用由{1}计算的pArray[3]的新值。

由于您的迭代不是独立的,因此循环不能直接并行化。

因为显然所有你想要的是将数组的值向前移动一个位置,我认为更好的方法是使用指针算法或重新组织你的循环和你的代码的其他部分来试图消除依赖或者完全循环。

答案 1 :(得分:2)

您想要的是并行执行import getpass, poplib success = False user = raw_input('Username: ') passw = getpass.getpass() #passw = raw_input('Password: ') R=poplib.POP3_SSL('pop.gmail.com',995) R.user(user) R.pass_(passw) 。这是一个做你想做的事的例子。

memmove

答案 2 :(得分:0)

您可以将数组分成多个块。 所以每个线程只能在他的块上工作。

例如,如果您的数组大小为1000,并且您有4个线程,则第一个线程将移动块1-198中的值,第二个块移动到块201-398中,依此类推。 不要忘记在边界上移动价值的特殊情况(例如200到199)

您不需要为'创建'只有' parallel'区域将是有用的。