循环中的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::asio::io_service创建线程池thread_group简单实例
C++ boost::asio::io_service创建线程池thread_group简单实例