Ask Your Question
1

Using SURF with TBB support: thread leak?

asked 2012-08-16 05:36:22 -0600

emilie gravatar image

Hi,

I am using Ubuntu 11.04 with OpenCV 2.4.2, compiled with TBB support (TBB version 3.0) with an Intel i5 processor (4 cores). I have tried using the parallelized version of SURF descriptors extraction. Either there is something I did not understand well, or there might be a thread leak.

The idea is that I create a SURF extractor, use it on an image, then continue on in my code. With TBB, 4 threads are created for this extraction, but they are not destroyed even when the extraction is done, ven when the extractor object does not exist anymore.

Here is a piece of code to illustrate this

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <iostream>
#include <time.h>

int main(int argc, char* argv[]) {
  if (argc != 2) {
    return 1;
  }
  cv::Mat img = cv::imread(argv[1], 0);
  // Scope where the extractor exists.
  {
    cv::SURF extractor;
    std::vector<cv::KeyPoint> keypoints;
    std::vector<float> descriptors;
    std::cout << "Beginning extracting." << std::endl;
    int counter = 0;
    // Extract several times to see things happening
    while (counter < 10) {
      extractor(img, cv::Mat(), keypoints, descriptors);
      sleep(1);
      ++counter;
      std::cout << "Iteration #" << counter << std::endl;
    }
  }
  // Now the extractor does not exist anymore
  std::cout << "Finished extracting." << std::endl;
  // Wait a bit to check the threads.
  sleep(10);
  std::cout << "Exiting" << std::endl;
  return 0;

}

If you run the program (giving an image path as an argument) and check the number of threads used, you can see that the for threads are created, but stay until the end of the program, even when the extracting is done and the extractor object does not exist. This looks to me like a thread leak...

So, do I misuse SURF extraction, is this a normal behavior, or a bug ?

Thanks in advance

Emilie

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2012-08-16 05:50:37 -0600

Vladislav Vinogradov gravatar image

TBB creates threads and TBB manages threads. I don't know exactly, but i think TBB uses some thread pool and creates threads only once. It's normal behavior to avoid unnecessary OS calls for threads creation.

edit flag offensive delete link more

Comments

It's true that TBB recycles the tread pool - once created, they are destroyed at exit, or by manually releasing them.

sammy gravatar imagesammy ( 2012-08-16 06:23:44 -0600 )edit

Well, I'm not sure that this is normal once all tasks are done. If you look here http://software.intel.com/en-us/blogs/2011/04/09/tbb-initialization-termination-and-resource-management-details-juicy-and-gory/ in the "termination" section, it looks like worker threads are supposed to be removed once the tasks are done (at least, shortly afterwards).

emilie gravatar imageemilie ( 2012-08-16 06:26:19 -0600 )edit

Read the bottom part, "Autoinitialization". Altohugh I cannot guarantee this is the way OpenCV works, I have a strong feeling that this is how it's used. And here is what they say about it:

In case of auto-initialization, local task dispatcher will be destroyed only when its thread exits. Often this happens only when the application completes. This means that auto-initialization, with all its convenience, may restrict your ability to control concurrency of parallel computations. The only consolation is that fortunately this is rarely an issue in practice.

sammy gravatar imagesammy ( 2012-08-16 06:46:27 -0600 )edit

Nice catch, had not seen that one... This looks exactly like my problem. I'll try to check if OpenCV uses auto initialization or not

emilie gravatar imageemilie ( 2012-08-16 06:50:41 -0600 )edit
1

Yes, as I see, OpenCV uses auto initialization by default.

Daniil Osokin gravatar imageDaniil Osokin ( 2012-08-16 07:26:46 -0600 )edit

You're right. The thing is, by simply adding

cv::Ptr&lt;tbb::task_scheduler_init&gt; tbb_init = new tbb::task_scheduler_init();

right before the extractor initialization, the threads behave nicely and disappear when the tasks are done

emilie gravatar imageemilie ( 2012-08-16 07:37:23 -0600 )edit
1

I think that would be bad for the library overall. Just look at this code. Suppose resize() uses TBB.

   for(;;)
   {
        capture &gt;&gt; frame;
        cv::resize(frame, smallerframe, smallerSize);
          ...
   }

Now, tons of threads will be created. Each frame will create, use and destroy its threads, which is a terrible waste. The model proposed by you is nice when you have control over the other aspects of the library, so you know when you do not need the threads anymore, and you can release them safely.

sammy gravatar imagesammy ( 2012-08-16 07:43:49 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2012-08-16 05:36:22 -0600

Seen: 822 times

Last updated: Aug 16 '12