C++ C++;OpenCV中的内存计数

C++ C++;OpenCV中的内存计数,c++,multithreading,opencv,memory-management,C++,Multithreading,Opencv,Memory Management,我有一个用OpenCV编写的应用程序。它由两个线程组成,每个线程执行一个OpenCV函数。如何确定每个线程生成的内存量 我正在使用libdispatch,grandcentraldispatch设计模式。在这个阶段,我可以同时运行多个任务。在这种情况下,我如何管理内存?有了一些opencv进程和足够多的并发任务,我可以轻松达到RAM上限。如何管理 < C++中使用什么策略?< /P> 如果每个线程都有内存限制,那么该如何处理呢 问候, Daniel我不熟悉您使用的调度库/模式,但我已经快速浏览了

我有一个用OpenCV编写的应用程序。它由两个线程组成,每个线程执行一个OpenCV函数。如何确定每个线程生成的内存量

我正在使用libdispatch,grandcentraldispatch设计模式。在这个阶段,我可以同时运行多个任务。在这种情况下,我如何管理内存?有了一些opencv进程和足够多的并发任务,我可以轻松达到RAM上限。如何管理

< C++中使用什么策略?< /P> 如果每个线程都有内存限制,那么该如何处理呢

问候,


Daniel

我不熟悉您使用的调度库/模式,但我已经快速浏览了一下它的目标。我在图像处理/视频处理领域做了大量的工作,所以希望我的答案不是完全无用的文字墙;)

我的怀疑是,您正在将整个图像缓冲区发送到不同的线程,以便在它们上运行相同的处理。如果是这种情况,那么您很快就会达到RAM限制。如果一个任务(线程)在其内部函数中使用了N个映像缓冲区,并且您的RAM为M,那么您可能会开始在M/N个任务(线程)中耗尽内存。如果是这种情况,那么您可能需要求助于将图像块发送到线程(请参阅下面关于使用依赖关系图进行处理的提示)

您还应该考虑在特定算法中的性能是内存绑定的,而不是CPU绑定的。因此,即使您有额外的内核,启动更多线程也可能是毫无意义的,在这种情况下,您最好专注于诸如SSE/MMX之类的CPU SIMD

首先配置文件,然后询问(内存分配器)问题 使用适合并发环境和特定内存需求的手动内存分配器可以大大提高性能。但是,它们不太可能减少您使用的内存量,除非您正在处理许多小对象,在这些小对象中,在分配和回收内存布局时,您可能比默认的malloc/free实现做得更好。当您使用图像处理算法时,后者不太可能。通常在堆上分配了大量的映像缓冲区,而不是许多小的ish结构

在我的答案的末尾,我将添加一些关于如何开始阅读滚动您自己的分配器的提示,但一般来说,我的建议是首先分析并找出内存的使用位置。在编写代码之后,您可能对代码的发展方向有很好的预感,但如果不是这样的话,像(复杂的beast)这样的工具可能会有很大的帮助

分析代码之后,找出如何减少内存使用。根据内存的使用情况,您可以在这里做很多很多事情。例如:

  • 一旦你用完了不需要的内存,就把它释放出来。我可以在这里派上用场
  • 除非需要,否则不要复制内存
  • 适当时在线程和进程之间共享内存。这将比处理不可变/复制的数据更加困难,因为您必须同步读/写访问,但根据您的问题情况,这可能会产生很大的不同
  • <> LI>如果使用内存缓存,并且由于性能原因,不想将数据缓存到磁盘,那么考虑到当它下降到最近最少使用的缓存的底部时,使用内存压缩(例如,压缩一些缓存),例如
  • 与其加载整个数据集并让每个方法对其整体进行操作,不如看看是否可以将其分块并仅对其子集进行操作。这在处理大型数据集时尤其重要
  • 查看是否可以使用较低的分辨率或精度,例如四分之一大小而不是全尺寸图像,或32位浮点而不是64位浮点(甚至是16位浮点的自定义库),或者一次仅使用一个图像数据通道(仅红色、蓝色、绿色或灰度而不是RGB)
当您使用OpenCV时,我猜您可能正在从事图像处理或视频处理。这些可以很容易地吞噬大量的内存。根据我的经验,最初的研发实现通常在一种方法中处理整个图像缓冲区,然后再将其传递给下一种方法。这通常会导致使用多个完整图像缓冲区,这在内存消耗方面非常昂贵。减少任何临时缓冲区的使用在这里都是一个巨大的胜利

另一种缓解这种情况的方法是,看看您是否能够找出数据依赖关系(例如,通过查看低通滤波器所需的ROI),然后处理较小的图像块,稍后再将它们连接起来,并尽可能避免临时重复缓冲区。以这种方式减少内存占用可能是一个巨大的胜利,因为您通常也在减少缓存丢失的机会。这种方法通常会使实现变得非常复杂,除非您有一个基于图形的框架已经支持它,否则在用尽其他选项之前,您可能不应该尝试这种方法。英特尔在优化线程图像处理应用程序方面拥有大量丰富的资源

内存分配器提示 如果您仍然认为使用内存分配器会很有用,下面是一些提示

例如,在Linux上,您可以使用

  • ,或
  • 例如,只需在主编译单元(main.cpp)、静态链接的库或预加载的共享库中重写它们
有几种优秀的malloc/免费替代品可供您学习,以获取创意,例如:

如果您处理的是特定的C++对象,那么可以重写它们的<代码>新< /COD>