循环中的升压Thread_Group非常慢
Boost Thread_Group in a loop is very slow
我想使用线程同时运行矢量中的多个图像。这是代码
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 的循环)的迭代不相互依赖,我建议您在整个最外层循环完成后加入线程。
- OpenGL大的3D纹理(>2GB)非常慢
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 使用浮点数和双精度数的非常小数字的数学
- 在打开多个其他窗口时使用全屏窗口时帧速率非常低
- 我从int x[3]得到的一个非常奇怪的输出;
- 反向迭代器在C++中非常奇怪的行为
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 我的自定义使用 std::unordered_map 的性能非常慢
- ifstream 尝试读取 9 到 13 之间的无符号字符时非常奇怪的行为
- 一个非常简单的win32套接字代码,但工作错误
- 非常快速地阅读 CSV 文件
- max_element() 给出非常奇怪的错误消息
- 将 mmap 内存用于开销非常低的循环缓冲区
- 内存映射文件访问非常慢
- 超过CPU时间限制:当MPI_Sent一个非常大的int*时
- QtWebengine 5.7.1的性能非常慢
- 如何非常快速地将数字添加到 Vector 中的一系列元素中
- 我在运行函数 GetVolumeInformation() 时得到非常随机的结果