循环中的Boost Thread_Group非常慢

时间:2016-02-26 03:10:57

标签: c++ multithreading boost

我想使用线程同时检查向量中的多个图像。这是代码

        boost::thread_group tGroup;
        for (int line = 0;line < sourceImageData.size(); line++) {
            for (int pixel = 0;pixel < sourceImageData[line].size();pixel++) {
                for (int im = 0;im < m_images.size();im++) {
                    tGroup.create_thread(boost::bind(&ClassX::ClassXFunction, this, line, pixel, im));
                }
                tGroup.join_all();
            }
        }

这将创建线程组并循环通过像素数据和每个像素的行,然后循环多个图像。它是一个奇怪的项目,但无论如何我将线程绑定到此代码所在类的同一实例中的方法,因此使用“this”。这会运行大约20个图像的数量,在每个线程结束时绑定,然后在完成循环时,join_all函数在线程完成时生效。然后它转到下一个像素并重新开始。

我使用这个简单的程序测试了同时运行50个线程

void run(int index) {
    for (int i = 0;i < 100;i++) {
        std::cout << "Index : " <<index<<"   "<<i << std::endl;
    }
}

int main() {
    boost::thread_group tGroup;

    for (int i = 0;i < 50;i++){
        tGroup.create_thread(boost::bind(run, i));
    }

    tGroup.join_all();
    int done;
    std::cin >> done;
    return 0;
}

这很快就能奏效。即使线程在前一个程序中绑定的方法更复杂,它也不应该像它一样慢。一个sourceImageData(line)循环完成需要4秒。我是新手来增强线程,所以我不知道嵌套循环或其他方面是否有明显的错误。任何见解都表示赞赏。

2 个答案:

答案 0 :(得分:0)

我相信这里的区别在于你决定加入主题。

在第一段代码中,您将在假定的源图像的每个像素处加入线程。在第二段代码中,您只在最后加入一次线程。

线程同步很昂贵,并且通常是并行程序的瓶颈,因为您基本上暂停执行任何新线程,直到需要同步的 ALL 线程,在这种情况下,所有线程都是活跃的,已经完成了。

如果最内层循环(带有im的循环)的迭代不相互依赖,我建议你在整个最外层循环完成后加入线程。

答案 1 :(得分:0)

答案很简单。不要启动那么多线程。考虑启动与逻辑CPU核心一样多的线程。启动线程非常昂贵

当然,从来没有只是做一个小工作就开始了。保留线程并使用任务队列为它们提供大量(小)任务。

请参阅此处以获取一个很好的示例,其中线程数同样是问题:boost thread throwing exception "thread_resource_error: resource temporarily unavailable"

在这种情况下,我认为你可以通过增加每个任务的大小来获得很多性能(不是每个像素创建一个,而是每个扫描线创建一个)