我正在构建一个应用程序,它将从摄像机源进行一些对象跟踪,并使用其中的信息在OpenGL中运行粒子系统。处理视频输入的代码有点慢,现在每帧200到300毫秒。将运行的系统具有双核处理器。为了最大限度地提高性能,我想将相机处理内容卸载到一个处理器,只是将相关数据传回主应用程序,同时让主应用程序在其他处理器上运行。
如何将相机工作卸载到其他处理器,以及如何处理与主应用程序的通信,我需要做什么?
编辑: 我正在运行Windows 7 64位。
答案 0 :(得分:12)
基本上,您需要多线程化您的应用程序。每个执行线程只能使一个核心饱和。单独的线程往往在不同的核心上运行。如果你坚持每个线程总是在特定的核心上执行,那么每个操作系统都有自己的方式来指定这个(亲和掩码等)...但我不推荐它。
OpenMP很棒,但它在屁股上有点胖,特别是在从并行化加入时。因人而异。它易于使用,但根本不是最好的选择。它还需要编译器支持。
如果您使用的是Mac OS X 10.6(Snow Leopard),则可以使用Grand Central Dispatch。阅读有趣,即使你不使用它,因为它的设计实现了一些最佳实践。它也不是最优的,但它比OpenMP更好,即使它也需要编译器支持。
如果您能够将应用程序分解为“任务”或“作业”,那么您可以将这些作业推到尽可能多的管道中。考虑将处理批处理为原子工作单元。如果你可以正确分割它,你可以同时在两个核心和主线程上运行相机处理。
如果每个工作单元的通信最小化,那么您对互斥锁和其他锁定原语的需求将被最小化。课程粒度线程比细粒度更容易。而且,您始终可以使用库或框架来减轻负担。如果采用手动方法,请考虑Boost's Thread library。它提供了便携式包装器和一个很好的抽象。
答案 1 :(得分:3)
这取决于您拥有多少核心。如果你只有2个核心(cpu,处理器,超线程,你知道我的意思),那么OpenMP不能提供如此巨大的性能提升,但会有所帮助。您可以获得的最大增益是将时间除以处理器数量,因此每帧仍需要100 - 150 ms。
等式为
parallel time =(([执行任务的总时间] - [无法并行化的代码])/ [cpus的数量])+ [无法并行化的代码]
基本上,OpenMP处理并行循环。它相当容易使用
#pragma omp parallel for
for (i = 0; i < N; i++)
a[i] = 2 * i;
然后爆炸,你的并行化了。它并不适用于所有情况,并非每种算法都可以通过这种方式并行化,但许多算法可以重写(黑客)以兼容。关键原则是单指令多数据(SIMD),例如将相同的卷积码应用于多个像素。
但是简单地应用这本食谱会违反优化规则
1 - 对您的代码进行基准测试
2 - 用“科学”证据(数字)找出真正的瓶颈,而不是简单地猜测你认为存在瓶颈的地方
3 - 如果它真的是处理循环,那么OpenMP适合你
对现有代码进行简单优化可能会产生更好的结果,谁知道呢?
另一条道路是在线程上运行opengl,在另一个线程上运行数据处理。如果opengl或粒子渲染系统需要很多功能,这将有很大帮助,但请记住,线程可能会导致其他类型的同步瓶颈。
答案 2 :(得分:2)
我建议不要使用OpenMP,OpenMP更适用于数字代码,而不是您似乎拥有的消费者/生产者模型。
我认为你可以做一些简单的事情,使用boost线程来产生工作线程,公共内存段(用于获取数据的通信),以及一些告知你的数据的通知机制(查看boost线程中断)。 / p>
我不知道你做了什么样的处理,但你可能想看一下英特尔线程构建模块和英特尔集成基元,它们有几个视频处理功能可能更快(假设它们具有你的功能) )
答案 3 :(得分:1)
您需要某种框架来处理多核。 OpenMP似乎是一个相当简单的选择。
答案 4 :(得分:0)
就像Pestilence所说的那样,你只需要你的应用程序是多线程的。已经提到了很多像OpenMP这样的框架,所以这是另一个框架:
我之前从未使用它,但我听到了很多关于它的事情。
希望这有帮助!