循环中的升压Thread_Group非常慢

Boost Thread_Group in a loop is very slow

本文关键字:Group 非常 Thread 循环      更新时间:2023-10-16

我想使用线程同时运行矢量中的多个图像。这是代码

        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;
}

这工作非常快。尽管线程在以前的程序中绑定到的方法更复杂,但它不应该像现在这样慢。完成一个源图像数据(行)循环大约需要 4 秒。我是提升线程的新手,所以我不知道嵌套循环是否明显出错。任何见解都值得赞赏。

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

当然,永远不要仅仅为了完成一项微小的工作而启动线程。保留线程并使用任务队列为它们提供大量(小)任务。

请参阅此处以获取一个很好的示例,其中线程数同样是问题: boost 线程引发异常"thread_resource_error:资源暂时不可用"

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

我相信

这里的区别在于您决定加入线程的时间。

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

线程同步是

昂贵的,并且通常是并行程序的瓶颈,因为您基本上暂停了任何新线程的执行,直到所有需要同步的线程(在本例中是所有处于活动状态的线程)都完成运行。

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