循环中的Boost Thread_Group非常慢

Posted

技术标签:

【中文标题】循环中的Boost Thread_Group非常慢【英文标题】:Boost Thread_Group in a loop is very slow 【发布时间】:2016-02-26 03:10:56 【问题描述】:

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

        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(行)循环大约需要 4 秒。我是增强线程的新手,所以我不知道嵌套循环是否有明显错误。任何见解都值得赞赏。

【问题讨论】:

【参考方案1】:

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

绝对不要为了做一件小事而启动线程。保留线程并使用任务队列为它们分配大量(小)任务。

有关线程数同样是问题的一个很好的示例,请参见此处:boost thread throwing exception "thread_resource_error: resource temporarily unavailable"

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

【讨论】:

谢谢,这有助于加快速度。我像你说的那样在第一个/主循环(行)下创建了一个线程,并将另外两个移动到线程调用的函数中。是否可以做其他任何事情来使其更快,例如清理,或者使其一次只有 8 或 10 个线程处于活动状态,并且只是正常调用该函数,直到“插槽”打开? 确保只有 n 个线程处于活动状态的方法是不要拥有更多线程。因此,它更多是关于巧妙地跨可用线程分块处理。您可能应该专注于任务不要太小(开销太大),也不要太大(并发太少)【参考方案2】:

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

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

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

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

【讨论】:

谢谢,这有助于加快速度

以上是关于循环中的Boost Thread_Group非常慢的主要内容,如果未能解决你的问题,请参考以下文章

如何让 boost::thread_group 执行固定数量的并行线程

C++ Boost,在类中使用 thread_group

C++ boost::asio::io_service创建线程池thread_group简单实例

C++ boost::asio::io_service创建线程池thread_group简单实例

c++ boost thread_group with asycron 返回

asio::io_service 和 thread_group 生命周期问题