【问题标题】:Multi core, make function called from inside function to run on second core. directshow, opencv多核,使从内部函数调用的函数在第二个核心上运行。直接展示,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”)?

谢谢!

【问题讨论】:

    标签: c++ multithreading opencv directshow multicore


    【解决方案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,那么您必须拥有它,其他像素格式不会适合您。
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 2016-01-22
    • 2022-05-20
    相关资源
    最近更新 更多