简体   繁体   English

在多线程环境中启动 std::async function 后,有什么方法可以加速 future.get() function?

[英]Is there any way to speedup the future.get() function after launching the std::async function in a multithreaded environment?

I have a correctly working code to process 1000 image files using openCV.我有一个使用 openCV 处理 1000 个图像文件的正确工作代码。 As the operation is independent of individual files, I have used multithreading using the std::async function.由于操作独立于单个文件,因此我使用std::async function 使用多线程。

I am launching the threads by following function call inside for loop.我通过在for循环中调用 function 来启动线程。

std::vector<std::future<cv::Mat>> processingThread;
for (int i = 0; i < jsonObjects.size(); i++) {
        processingThread.emplace_back(std::async(std::launch::async, (cv::Mat(CameraToBEV::*)(json&, std::vector<cv::Point2f>, cv::Point2f, cv::Point2f)) & CameraToBEV::process, &cbevVec[i], std::ref(jsonObjects[i]), roiBox1, opDim,ipDim));
    }

Above code is working fine and taking about 100 milliseconds .上面的代码工作正常,大约需要100 毫秒 But to collect the results I am using another for loop as follows;但是为了收集结果,我使用了另一个for循环,如下所示;

std::vector<cv::Mat> opMatArr;
for (auto& future : processingThread) {
        opMatArr.emplace_back(future.get());
       }

This is also working fine but it is taking 9 seconds to execute, which kind of defeating the purpose of using multithreading as I am sequentially populating the vector of cv::Mat objects.这也可以正常工作,但执行需要9 秒,这违背了使用多线程的目的,因为我正在按顺序填充cv::Mat对象的向量。 Is there any way like, parallelly, as in, in few milliseconds I should be able to get all the cv::Mat objects in the std::vector opMatArr ?有没有什么方法可以并行地在几毫秒内获得std::vector opMatArr中的所有cv::Mat对象?

Several things come to mind:想到几件事:

  1. You say this is "defeating the purpose of using multithreading".你说这是“违背了使用多线程的目的”。 What is the runtime of this code if you run it sequentially (ie remove the multithreading code and process each image in a loop)?如果您按顺序运行此代码(即删除多线程代码并循环处理每个图像),该代码的运行时间是多少? I would bet it's a lot more than 9 seconds.我敢打赌,这远远超过 9 秒。

  2. The std::async calls only create the task/thread/whatever, but don't start it, nor do you have any guarantee it will finish after a certain time. std::async调用仅创建任务/线程/任何内容,但不启动它,也不保证它会在一定时间后完成。 When you call get() , you force your program to wait on it, and a decent C++ library will yield execution to the thread you're waiting on.当您调用get()时,您会强制您的程序等待它,并且一个不错的 C++ 库将执行您正在等待的线程。 This is not a strict guarantee, but any behaviour otherwise would make this kind of code useless from the start.这不是一个严格的保证,但否则任何行为都会使这种代码从一开始就毫无用处。 Measuring the startup of the threads is useful but doesn't do much in the sense of measuring how long the actual operation takes (unless the overhead of the threads is larger than the runtime of the combined operations).测量线程的启动很有用,但在测量实际操作需要多长时间的意义上并没有多大作用(除非线程的开销大于组合操作的运行时间)。

  3. You should std::move the result from the future.您应该std::move未来的结果。 It seems like you may be creating a copy of the data, which may be impacting performance for no good reason.看起来您可能正在创建数据的副本,这可能会无缘无故地影响性能。

  4. Creating this amount of threads will irrevocably lead to contention of resources, be it disk or memory bandwidth, CPU, or even memory size.创建这么多线程将不可避免地导致资源争用,无论是磁盘还是 memory 带宽、CPU,甚至是 memory 大小。 In general it is better to set up a thread pool of sorts, in which N threads (where N is the amount of cores or "multithreaded cores" available on the system), and some sort of task queue that handles starting new jobs when threads free up.一般来说,最好设置一个线程池,其中有 N 个线程(其中 N 是系统上可用的核心数量或“多线程核心”),以及一些任务队列,当线程处理启动新作业时释放。 Note that std::async may indeed already do this under the hood (as far as I remember an implementation is free to implement this with pooling or not, also dependent on other options passed to std::async ).请注意, std::async可能确实已经在后台执行此操作(据我所知,实现可以自由地通过池来实现这一点,也取决于传递给std::async的其他选项)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM