Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Pipeline and tbb thread

hitach__0
Beginner
732 Views
My project is in image processing.My task is read a video, do processing and display frame in sequence, that is i have to display framein every 30ms. I wrote code as shown below.


[bash]int main()  
{  
    volatile bool stop = false;  
    thread_obj obj(stop);

    tbb::tbb_thread t (obj);  
    ...  
    //pipeline code goes here. input_filter(serial), transform_filter1(parallel),    
    //transform_filter2(serial), transform_filter3(parallel),   output_filter(serial)
    ...  
    pipeline.run(...); 
    pipeline.clear();
    stop = true;  
    t.join();  
}  
  

//thread_obj's class
thread_obj::thread_obj(bool volatile& st){
     stop=st;
}

void thread_obj::operator ()()
{
    while(stop==false){
        //display image
         tbb::this_tbb_thread::sleep(tbb::tick_count::interval_t(0.03));  
    }
}
 [/bash]


however after doing above code, i get fast output, but in serial mode
(tbb::task_scheduler_init init_parallel(1)) i got faster output thantask_scheduler_init::automatic.
18sec video clip runs
serial mode - 33 sec, 60%processer usage without sleep it takes 30sec to finish it works
parallel mode - 54 sec, 100%processer usage without sleep it takes 23sec to finish it works

but i found that in my program, it finished all compilation time in around 15sec in parallel mode rest are time are used for display image every 30ms, but in serial mode it runs until end of time.

may i know why it is slow in parallel mode? is there is anypossibilityto improve speed?
is it possible to set priority of thread_obj. because it takes 40s to display only images. therefore if we post pond our some processing task in first 15 sec then we get fast output. I think we can do it using setpriority. That is if force display_thread to display image in every 30ms then we can get fast output.
how to do that?
0 Kudos
14 Replies
nagy
New Contributor I
732 Views
I think you will have to post the rest of the code if you want help. It sounds more like a implementation problem with spinning orunnecessaryblocking than a tbb problem.

There are a few problems I can see though. First of all don't use "volatile bool" but tbb::atomic.
The display frame loop should look something like:
while(!stop)
{
Frame* myFrame = frameQueue_.pop(); // blocking wait
if(myFrame == nullptr)
stop = true; // eof
else
{
double delta = currentTime - lastTime;
sleep(1.0/fps - delta);
display(myFrame);
lastTime = currentTime;
}
}
0 Kudos
hitach__0
Beginner
732 Views
thank u for ur reply, i could not able to upload my all code, because it is big.
My problem is hw to control both display thread and pipeline thread. because display thread get low priority.
why your saying that"volatile bool" is not good?insteadof that what i can use. i ddnt get abouttbb::atomic.
0 Kudos
nagy
New Contributor I
732 Views
you dont need to upload all your code... just the relevant bits... I would guess the output filter and the display function...

I'm in no way an expert but I dont think its a problem of thread priority.
volatile does not guarantee atomic operations in C++ and is not useful for threading... it has other purposes...
0 Kudos
RafSchietekat
Valued Contributor III
732 Views
If you don't assume any memory semantics, using a volatile bool should work on all compilers, maybe even with less overhead than tbb::atomic's read+acquire, although I haven't benchmarked that.

Pausing inside a TBB worker thread is rather suspicious, because that thread can't do anything more useful at the same time, or at least it is not documented that even TBB's own sleep() will switch to another task in the meantime. Before doing anything else, I'd try to get rid of that.
0 Kudos
hitach__0
Beginner
732 Views
"that thread can't do anything more useful at the same time"
that thread is only for displaying image, not for any other purpose.
pipeline thread has all the use full works. so how to switch both threads.. I thought we can do it based on priorities. What is the best way to switch both threads?
@addition: my output_filter put all the processed video in a concurrent queue andthread_obj hasreferenceto that queue.
0 Kudos
RafSchietekat
Valued Contributor III
732 Views
Sorry, I missed that point.

Here's just a wild guess: worker threads spin for a while before they go to sleep, and the original thread never goes to sleep, so with many short waits to get something between the second and third filters much of that thread's time is spent busy-waiting, but I'm not sure whether anything could be done about that. The queue probably also spins for a while before going to sleep, so maybe the display thread should try to get the next frame just in time instead. Does this seem plausible to anyone else?

(Added) If there's only TBB work, worker thread spinning shouldn't be a problem, but perhaps the non-TBB spinning (in a TBB queue, but not in a TBB worker thread) badly interacts with that somehow, and getting rid of much of the non-TBB spinning might provide relief?
0 Kudos
hitach__0
Beginner
732 Views
ya.. due to spinningit may slow, but in serial mode it woks well.
I am not usinganythingother than tbb thread.
so what is the solution for my project. just use pipeline? is there is anyway to increase the speed. I have optimize code, therefore i cant further increase speed in code wise.
0 Kudos
RafSchietekat
Valued Contributor III
732 Views
"I am not using anything other than tbb thread."
That's just an API: the intended distinction was that some threads are TBB master/worker threads (typically as many as configured in task_scheduler_init), and one is an independent extra user thread (even if it is managed by a tbb_thread object), if that's the appropriate terminology.

"so what is the solution for my project. just use pipeline?"
No, as suggested in #6 you might try to sleep() first and only then pop() an item from the queue, where it will probably already be ready for the taking. Perhaps this helps, perhaps not, but I would certainly give it a try.
0 Kudos
Alexey-Kukanov
Employee
732 Views
What is the hardware you use?
And where those 15s of "compilation time" you mentioned came from?Is it the time taken by pipeline.run()in the main thread?
And do you have the desired 30 fps when the pipeline is running at full gear?
0 Kudos
hitach__0
Beginner
732 Views
where those 15s of "compilation time" you mentioned came from?
i just stop display thread and run other all program. ya i measure pipleline.run(). because all the main task are runs in pipeline. for serial one it takes normal time(more than 35sec)
when i run pipeline(in serial mode), i can able to get round 20-25 fps. But by using parallel processing and pipeline i can get good result without displaying image, compare to serial one. Problem ismanagingtwo thread, that is pipeline and display frame thread.
0 Kudos
hitach__0
Beginner
732 Views
you might try to sleep() first and only then pop() an item from the queue.....
i am following same procedure, when thread wakeups, there are image in queue.
what happening is, first ~20sec it finishes it all the process as the same time itdisplayframe. But display thread is not wake up in every ~30ms it gives high priority to pipeline, therefore display image s not sequence in first 20sec after that it display in sequence.rest of time is only for display image, that means it goes to sleep every 30ms, during those time none of works are done by both thread.
0 Kudos
RafSchietekat
Valued Contributor III
732 Views
I'm sorry, I didn't understand that.
0 Kudos
hitach__0
Beginner
732 Views
you might try to sleep() first and only then pop() an item from the queue, where it will probably already be ready for the taking.
i am following same procedure, i put thread to sleep() and pop() anitemfrom the queue in every 30ms.

currently my system works like following:
In the first 20sec(nearly), it finishes all the pipeline process, as the same time it popup frame from queue and display image.But display thread is not wake up in every 30ms. because pipeline works has high priority, therefore display image is not sequence in first 20sec. but after that it display insequentialorder (every 30ms).after 20sec only display thread is working and it goes to sleep every 30ms, during those time none of works are done by both thread.
0 Kudos
RafSchietekat
Valued Contributor III
732 Views
I'm still having trouble understanding exactly what's going on.

Assuming that you are finding that the display thread is falling behind during the time that the pipeline is filling up the queue and then has some time left where it operates normally, you might try one or more of the following: increase the priority of the display thread using pthread_setschedparam() or whatever applies to your O.S. (assuming that when it is scheduled to wake up it will preempt lower-priority threads), yield inside the pipeline, e.g., after pushing a frame onto the queue, or throttle frame production, e.g., by using a bounded queue. The last 2 will likely provide only partial relief for the real-time constraints of smooth display, though.

Is that useful at all?
0 Kudos
Reply