【问题标题】:How do I parallelise a for loop, using `omp parallel` or otherwise?如何使用“omp parallel”或其他方式并行化 for 循环?
【发布时间】:2018-05-22 19:12:19
【问题描述】:

假设我有三个整数向量:

  • 大小为 800 万个元素的 mainVect
  • 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

或任何其他方法...

附: Windows google cloud machine, n1-standard-4 (4 vCPUs, 15 GB memory) .. 运行上述代码时 CPU 利用率仅为 27%。

【问题讨论】:

  • 如果您不编写使用多线程的代码,那么您拥有多少内核是无关紧要的。我不是这种语法方面的专家,但怀疑你写的内容告诉编译器如何并行化你的循环,而不是只告诉编译器如果你 并行化它们应该如何共享这些变量。
  • CPU 使用率只有 27% 暗示您的并行化不起作用...
  • 你能排序mainVect吗?
  • 对于矢量运算,您可以使用 gpu。
  • 我认为任何数量的线性加速都无济于事 - 你有 12000 亿次 次迭代。优化使用四个核心将等待时间减少到相当于三千亿。 (每次迭代一纳秒 - 我认为这是乐观的 - 从三个多小时到不到一小时。)另一方面,首先计算 mainVect 的元素,然后进行 150 万次表查找可能会缩短时间几秒钟。

标签: c++ multithreading parallel-processing


【解决方案1】:

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,这非常快。

【讨论】:

  • 我喜欢这个。它基本上使用与我相同的想法,但使用关联容器可能比排序快得多。我不是 C++ 专家,不知道盒子里有什么工具,但我知道如何排序 :-) 事实上,机器人方法的性能很容易胜过多线程。
【解决方案2】:

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

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

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

我的做法是:

  1. 对 mainVect 进行排序
  2. 将 mainVect 转换为由“键”和出现次数组成的表
  3. 对 vect1 进行排序并创建一个间接向量。迭代这个间接向量会给出升序中的“键”
  4. 现在您可以“合并”了

这种方法的复杂度是 O(n log n)

【讨论】:

  • 我无法对 mainVect 进行排序
  • @noor 然后取 mainVect 的索引向量并对该向量进行排序
  • 为什么不呢?你不需要就地排序。您还可以使用@UKmonkey 建议的间接表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 2021-08-20
  • 1970-01-01
  • 2021-03-22
相关资源
最近更新 更多