多核,使从内部函数调用的函数在第二个核心上运行。直接展示,opencv

Posted

技术标签:

【中文标题】多核,使从内部函数调用的函数在第二个核心上运行。直接展示,opencv【英文标题】:Multi core, make function called from inside function to run on second core. directshow, opencv 【发布时间】:2013-05-13 11:36:18 【问题描述】:

所以,我一直在使用 opencv 开发一个实时跟踪系统。几天前,我不得不开始使用 directshow(这对我来说是全新的),因为我需要来自网络摄像头的更高分辨率。分辨率越高,CPU 使用率越高。当只使用没有任何 opencv 算法的 directshow 时,cpu 以 50% 的速度运行。 (我有双核 = 100% 使用一个核)

所以现在我需要扩展这个系统,以便使用我的两个内核。

我从 microsoft 找到了这个很好的示例,并且能够使用我的两个内核运行它:

void test1()
    parallel_invoke(
        []()  run1(); ,
        []()  run2(); 
    );

这运行得很好,我可以使用大约 85% 的总 cpu(只有 2 个带有循环的函数)。 现在我想在我的其他系统中使用它。而且我不知道该怎么做。

我的系统的简短描述:

int main()
     startDirectshow()
;

startDirectShow()
     //code for creating the directshow filter graph. including iSampleGrabber filter.


sampleCallBackFunction(....)
      // function called for every frame in the graph

到目前为止,一切都在工作,每帧都会调用 sampleCB(或每秒至少多帧,使用它时可能会丢失帧?!)

我的想法是让“sampleCallBackFunction()”在第二个核心上运行(我不想将它锁定到特定的核心,只使用第一个可用的核心)

但我发现的示例同时从同一个地方启动了两个函数。是否有可能以某种方式告诉系统“sampleCallBackFucntion”应该在另一个内核上运行?

我的另一个想法是将数据存储在“sampleCallBackFunction()”中,并将布尔值“newFrameAvailable”设置为 true。并让另一个线程从全局数组中提取数据。

while(true)
    If (newFrameAvailable)
         get-next-frame-in-buffer-and-do-opencv-algorithm();
    
    else
         do-nothing();
    

所以。我的问题:如何从另一个函数内部调用一个函数(从“startDirectshow”调用“sampleCallBackFunction”)?

谢谢!

【问题讨论】:

【参考方案1】:

您的问题不太清楚,但我想您想在另一个线程中调用sampleCallbackFunction。 (函数通常在另一个函数内部调用,这使得调用堆栈......)

因为 DirectShow,您的 sampleCallBackFunction 很可能已经在与您的主线程不同的流式线程上运行。当然,流线程上发生的所有事情都是一个逻辑核心的负担。

然后,如果您在 sampleCallbackFunction 创建另一个线程,您的系统足够智能,可以将工作分配到可用内核上,这不是问题。但我怀疑parallel_invoke 是否能让你灵活地做你必须做的事情,如果你真的想在那里再找一个工人,我建议寻找CreateThread

顺便说一句:在 GUI 应用程序中,在另一个线程中调用函数的最简单方法是使用 SendMessage,因为调用总是分配给创建窗口的线程。尽管如此,该呼叫仍处于阻塞状态...

【讨论】:

感谢您的回答。你是对的,我想为 samplerCallbackFunction 创建一个新线程,它使用另一个 cpu-core。但我想知道,如果我的系统应该将负载分配到可用内核上,为什么我不能将 cpu 使用率提高到 50% 以上?第二个核心运行 av ~4%,我的软件需要 moooore cpu 电源:D(我的视频输出很差。) 要利用资源,必须先创建工作线程。在这种情况下,您的主线程(大部分)处于空闲状态(仅管理过滤器图),而流线程正在从相机中获取帧。单个线程不能使用多个逻辑核心。 我查看了“资源监视器”,发现我的软件有 7 个线程处于活动状态。而且我还看到有几次它的 CPU 使用率高达 52%。这一定意味着一切都已经在多核上运行了,我不需要关心这个?!【参考方案2】:

首先,您可能希望更好地检查究竟是什么导致您的 CPU 过热高达 50%,而无需处理。最有可能的是,它转换为 RGB 颜色空间,您可以通过在另一个像素格式域中处理视频来避免。裸视频捕获不需要那么高的 CPU 使用率值。

如何从另一个函数内部调用一个函数(“sampleCallBackFunction”是从“startDirectshow”调用的)?

如果您想并行处理和/或在处理数据时继续捕获,这并不是您真正想要做的。 startDirectshow 线程是一个控制线程,它启动/停止处理并启动内部流线程。与控制线程同步不会提高性能,但会带来(a)同步开销和(b)终止死锁的机会。

如果您想并行处理,您需要在您的示例抓取回调中复制数据并尽快退出回调。然后一个线程池,例如TPL 或您自己的线程池,将在不影响捕获性能的情况下进行异步处理。

【讨论】:

抱歉,目前我认为这对我来说有点复杂。带有任务并行库。你问我的第二个选择吗?我想我需要阅读一下。 关于cpu过热。我在 1.3GHz、3GBram、64 位的笔记本电脑上运行它。它已经有几年的历史了。显卡很差。我正在通过 samplegrabber 将输入转换为 RGB。这可能是为什么我的 cpu 上升到 50% 的原因吗?我正在做这个直接的东西来获取数据到我的opencv软件。你知道是否有比 rgb 更好的色彩空间来转换?谢谢! 我不知道这个 TPL/async 我是如何工作的。我是否应该创建另一个从堆栈中提取数据的任务,如果它是空的,它只是等到有可用的帧? (就像我的问题中的第三个代码块?)我可以在谷歌上搜索什么来找到关于这个的更多信息?谢谢! 由您决定是否需要 RGB 进行处理。如果您将数据转换为典型的 RGB,您将自动插入转换。这可能并不明显,但可能会严重影响性能。出于这个原因,您可能需要检查一下并确保您了解发生了什么。但是另一方面,如果您的处理算法需要 RGB,那么您必须拥有它,其他像素格式不会适合您。

以上是关于多核,使从内部函数调用的函数在第二个核心上运行。直接展示,opencv的主要内容,如果未能解决你的问题,请参考以下文章

函数内部 sed 命令中的 bash 语法错误,在命令行上工作正常

在第二个脚本函数中传递来自第一个 python 脚本主函数的数据

在第二个 axios api 调用上获取错误 400 错误请求

菜单栏未显示在第二个窗口上

如何在python脚本中默认情况下在第二个TFT屏幕上运行套接字服务器控制台,而不是在主TFT屏幕上?

如何在第二个视图控制器上显示核心数据?