如何使用`omp parallel`或其他方式并行化for循环?

时间:2017-12-08 14:10:44

标签: c++ multithreading parallel-processing

假设我有三个整数向量:

  • mainVect,大小为800万元素
  • vect1,大小为150万元素
  • vect2,大小为150万元素

我想运行以下代码:

int i,j;
for ( i = 0; i < vect1.size(); i++)
{
    for ( j = 0; j < mainVect.size(); j++)
    {
        if (vect1[i] == mainVect[j])
        {
            vect2[i]++;             
        }
    }
}

花了很长时间没有完成...我如何加快运行速度,我有多处理器。试一试,我在上一段代码之前添加了以下句子(我读到它并行运行)

#pragma omp parallel for private(i, j) shared( mainVect, vect1, vect2)

但仍然很慢......

如果我将for循环分成4个部分;例如,我如何使这些for循环同时运行,如

for ( i = 0; i < vect1.size()/4; i++)
{

}

for ( i = vect1.size()/4; i < vect1.size()/2; i++)
{

}
.... and so on

或任何其他方法......

P.S .: Windows google云计算机,n1-standard-4(4个vCPU,15 GB内存)。运行上述代码时,CPU利用率仅为27%。

2 个答案:

答案 0 :(得分:4)

800万英镑不占用太多空间。您可以使用unordered_map或其他一些有效的关联容器。

unordered_map<int, int> umap;
for (int v : mainVect) {
    umap[v]++;
}
for (int i = 0; i < vect1.size(); ++i) {
    if (umap.count(vect1[i])) {
        vect2[i] += umap[vect1[i]];
    }
}

这个需要线性时间来填充vect2,这非常快。

答案 1 :(得分:3)

使用线程是一种可能的解决方案。

但主要问题是:你想解决什么问题?

如果我理解正确,你计算vect1中元素的mainVect中出现的次数。由于您不需要知道在哪里,您可以重新排列(副本)mainVect。

我的方法是:

  1. 排序mainVect
  2. 将mainVect转换为由“key”和出现次数组成的表
  3. 对vect1进行排序并创建一个间接向量。迭代此间接向量以递增顺序给出“键”
  4. 现在你可以“合并”
  5. 这种方法的复杂性是O(n log n)