Ask Your Question
0

connectedComponentsWithStats Problem in Multithread

asked 2018-11-15 03:47:42 -0600

milad gravatar image

updated 2018-11-15 05:09:53 -0600

Why does this code sometimes (maybe 5% of the times) return "5 4" instead of "5 5"? connectedComponentsWithStats should be executed inside 5 threads but sometimes one of them ruins things.

// std::atomic<int> first = 0, last = 0;
ThreadPool pool(thread::hardware_concurrency()); // 2 threads
for (int i = 0; i < 5; i++) {
    pool.enqueue([i, binaryImg] { // Add the thread.
        first++;
        Mat labels, stats, centroids;
        int objCount = connectedComponentsWithStats(binaryImg, labels, stats, centroids, 8); // PROBLEM. Sometimes the following lines inside this block won't be executed.
        last++;
    });
}
pool.~ThreadPool(); // Join all the threads.
cout << first << ' ' << last << endl;

Is there any problem with connectedComponentsWithStats when used in multiple threads? A weird problem to me because it gives no errors.

edit retag flag offensive close merge delete

Comments

did you find a note anywhere, that this funcion would be threadsafe ?

berak gravatar imageberak ( 2018-11-16 01:07:06 -0600 )edit

@berak the threads have their own variables. Can't find any issues with the thread itself. I usually use functions in threads unless the doc warn me. So you think this function isn't threadsafe? What is the solution? Do you recommend using a mutex lock for connectedComponentsWithStats?

milad gravatar imagemilad ( 2018-11-16 02:26:03 -0600 )edit

no, the function itself might not be threadsafe to use. (it's also using parallel_for_ already internally)

berak gravatar imageberak ( 2018-11-16 02:33:30 -0600 )edit

@berak To me it looks like a bad design. Because connectedComponentsWithStats can be used frequently in parallel programs. I might have to create a thread-safe function for running connectedComponentsWithStats.

milad gravatar imagemilad ( 2018-11-16 03:12:52 -0600 )edit

@berak What is the solution when using parallelized OpenCV functions in different threads? I had the same problem a few days ago.

kbarni gravatar imagekbarni ( 2018-11-16 03:15:59 -0600 )edit

@kbarni, yes, i've seen it ;(

@milad, the devs assume , you don't use multithreading (and so they're allowed to do weird optimization tricks, that might break your code)

you can try to disable the internal optimizations, but i somehow doubt, that doing this, and using your own multithreading on top of it is the right way to go, at all.

sorry, i don't have an easy or concise answer.

berak gravatar imageberak ( 2018-11-16 03:21:17 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-11-16 03:25:29 -0600

kbarni gravatar image

updated 2018-11-16 03:54:53 -0600

As connectedComponentsWithStats is already parallelized, it should run efficiently on your computer, no need to multithread. You'll lose more than you'll win. I tried it, and putting this function in parallel threads actually increased the processing time.

If you still need to run connectedComponentsWithStats in concurrent threads, you have to disable the parallelization inside the function.

In the file modules/imgproc/src/connectedcomponents.cpp (from the OpenCV source) change the line:

const bool is_parallel = currentParallelFramework != NULL && numberOfCPUs > 1 && L.rows / numberOfCPUs >= 2;

to:

const bool is_parallel = false;

and recompile/reinstall OpenCV. It will solve the problem.


[EDIT] some explanations at the end: why did I prefer to disable the internal optimizations?

In my case I'm capturing a video stream and doing different processing in parallel (let's call them A, B and C). Some are fast, and some are slower. I want each process to take the images as fast as it can. Let's say process A can take every image, process B every third image and process C every tenth image. And I don't want process C to block the other processes, so I need to run them in parallel. Originally some threads were hanging, but by disabling internal parallelization on connectedComponentsWithStats I can run them efficiently.

edit flag offensive delete link more

Comments

I just want to mention that the thread I'm using connectedComponentsWithStats inside it has more code inside. I didn't make my program multi-thread specifically for connectedComponentsWithStats.

milad gravatar imagemilad ( 2018-11-16 03:49:24 -0600 )edit

I'm in the same case; I added some explanations at the end of my answer. Unfortunately I didn't find any easier solution.

kbarni gravatar imagekbarni ( 2018-11-16 03:57:44 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-11-15 03:47:42 -0600

Seen: 779 times

Last updated: Nov 16 '18