如何并行化使用 boost?

Posted

技术标签:

【中文标题】如何并行化使用 boost?【英文标题】:How can I parallelize a for using boost? 【发布时间】:2012-10-08 15:45:46 【问题描述】:

为了优化我正在制作的一些库的执行,我必须并行化一些计算。 不幸的是,我不能为此使用 openmp,所以我正在尝试使用 boost::thread 做一些类似的替代方案。 有人知道这样的实现吗? 我在线程之间共享变量时遇到特殊问题(将变量定义为openmp的“共享”和“私有”)。有什么建议吗?

【问题讨论】:

如果我错了,请纠正我,但这似乎回答了你的问题***.com/questions/10155457/… 是的,但是'c++11'的功能并没有完全移植到苹果的'llvm-clang'编译工具上,所以我对c++11和openmp也有同样的问题。这两个系统,甚至更简单,但不能在所有平台上使用 【参考方案1】:

据我所知,除了 OpenMP 之外,您必须明确地执行此操作。

例如,如果我们在 OpenMP 中有一个并行循环

int i;
size_t length = 10000;
int someArray[] = new int[length];

#pragma omp parallel private(i)


    #pragma omp for schedule(dynamic, 8)
    for (i = 0; i < length; ++i) 

        someArray[i] = i*i;

    

您必须将逻辑分解为一个“通用”循环,该循环可以处理您的问题的子范围,然后明确安排线程。然后每个线程将处理整个问题的一部分。这样,您就可以显式声明“私有”变量——进入 subProblem 函数的变量。

void subProblem(int* someArray, size_t startIndex, size_t subLength) 
    size_t end = startIndex+subLength;

    for (size_t i = startIndex; i < end; ++i) 
        someArray[i] = i*i;         
    


void algorithm() 

    size_t i;
    size_t length = 10000;
    int someArray[] = new int[length];
    int numThreads = 4; // how to subdivide
    int thread = 0;

    // a vector of all threads working on the problem
    std::vector<boost::thread> threadVector;

    for(thread = 0; thread < numThreads; ++thread) 
        // size of subproblem
        size_t subLength = length / numThreads;
        size_t startIndex = subLength*thread;

        // use move semantics to create a thread in the vector
        // requires c++11. If you can't use c++11,
        // perhaps look at boost::move?
        threadVector.emplace(boost::bind(subProblem, someArray, startIndex, subLength));            
    
    // threads are now working on subproblems

    // now go through the thread vector and join with the threads.
    // left as an exercise :P


上面是许多调度算法之一 - 它只是将问题分成与线程一样多的块。

OpenMP 方法更复杂——它将问题分成许多小块(在我的示例中为 8 个),然后使用工作窃取调度将这些块提供给线程池中的线程。实现 OpenMP 方式的困难在于您需要等待工作的“持久”线程(线程池)。希望这是有道理的。

更简单的方法是在每次迭代中执行异步操作(为每次迭代安排一项工作)。如果每次迭代都非常昂贵并且需要很长时间,这可以工作。但是,如果它是具有多次迭代的小块工作,则大部分开销将用于调度和线程创建,从而使并行化变得无用。

总之,根据您的问题,有许多种方法来安排工作,您可以自行决定哪种方法最适合您的问题。

TL;DR: 如果您提供“子范围”功能,请尝试为您安排的英特尔线程构建模块(或 Microsoft PPL):

http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=14

【讨论】:

TBB,或微软的 PPL。 +1(过度?)全面的答案:) @sehe 呵呵,我有点得意忘形了:P 感谢您的回复。 TBB 很棒,但是在 Win、Linux 和 MacOSX 上使用 TBB 相对容易,但很难将代码移植到 iosandroid,所以我不能使用 TBB 库来实现。

以上是关于如何并行化使用 boost?的主要内容,如果未能解决你的问题,请参考以下文章

如何并行化 R 中包的函数

如何在Windows上进行并行化 - 例如?

如何使用dask.distributed并行化嵌套循环?

如何使用 python Ray 在一个大列表上并行化?

如何从 pytorch 模型并行化模型预测?

如何使用 OpenMP 并行化最近邻搜索