1

Several functions in a C++ OpenCV project I am working on use local Mat (and UMat) variables as temporary buffers for internal computations.

I would like to prevent these functions to allocate memory for all their local Mat variables every time they are called. The purpose of this is not to use less memory, but to make sure memory is available or fail at the first call and to prevent any possible overhead due to memory allocation.

To prevent reallocations, I thought about declaring the local Mat variables as static and making sure they will always store the same data size and type within the functions, despite I do not care about carrying the data they store across multiple calls.

Does this approach make sense? Am I doing it the wrong way, or is there a better/safer one?

Gianni
  • 458
  • 5
  • 17
  • 1
    OpenCV has a built-in mechanism to avoid this, so you should avoid what you are trying to do, because you will not have any benefit from it besides making "spaghetti" code. – Ricardo Alves Aug 31 '18 at 14:02
  • It absolutely doesn't make any sense. What makes you think that memory reallocations are causing any kind of problems in your code? – pptaszni Aug 31 '18 at 14:04
  • @ricardo Any references for the built-in memory allocation mechanism I could read?@ptaq My code runs on a systems the resources of which are used by other code as well. I want to make sure I can reserve all the bulky memory my project needs or just fail at startup. – Gianni Aug 31 '18 at 14:12
  • I'm pretty sure I already read a better article on this subject, but I found this: https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html. It's not complete but: "(...) As a nice bonus if you pass on an already existing Mat object, which has already allocated the required space for the matrix, this will be reused. In other words we use at all times only as much memory as we need to perform the task. (...) The last thing we want to do is further decrease the speed of your program by making unnecessary copies of potentially large images." – Ricardo Alves Aug 31 '18 at 14:39
  • 1
    Rather than using static variables, I'd wrap the code in question in a class and use member variables. (Then you can use the code in multiple threads, if needed, as opposted to function with static variables) One quite noticeable benefit will be on performance, since the repeated allocations of large arrays do have overhead. On 32bit platforms, it will help mitigate address space fragmentation. | IOW yeah, makes sense, I've used similar techniques in several systems that have been running in production 24/7 for years now. – Dan Mašek Aug 31 '18 at 15:05
  • My functions are actually methods of a class. I was using static variables in the single method as they are specific to that method should not be accessed by other methods of the same class. Any benefit from moving them to member variables in this case? – Gianni Aug 31 '18 at 15:10
  • 1
    @Gianni See [this](https://stackoverflow.com/questions/6223355/static-variables-in-member-functions/6223371). You won't be able to use that class (or specifically that function) in multiple threads safely. – Dan Mašek Aug 31 '18 at 18:03
  • Thanks! These 2 comments would make an accepted answer @dan – Gianni Sep 02 '18 at 10:27

1 Answers1

1

From personal experience, an approach of reusing temporary cv::Mat objects in repeated iterations is a useful and sensible approach.

One significant benefit is avoiding the constant reallocation of relatively large arrays, which tends to carry a noticeable overhead. Furthermore, at least on 32bit platforms, it helps to limit address space fragmentation (which becomes noticeable when your program runs for a long time).

However, I wouldn't use static variables, since that will generally reduce the reusability of your code (especially when you want to take advantage of parallelization). This Q/A will provide some additional explanation on why that is the case.

You could either provide reference(s) to the persistent context as a parameter, or perhaps implement something like a functor, or just use member variables in your class...

Dan Mašek
  • 17,852
  • 6
  • 57
  • 85