I am following this tutorial to understand how to remove locks , using VTUNE
This page says the following after collecting Vtune results:
Identify the Hottest Code Lines
Click the hotspot navigation button
to go to the code line that took the most Wait time. VTune Amplifier
highlights line 170 entering the critical section rgb_critical_section
in the draw_task function. The draw_task function was waiting for
almost 27 seconds while this code line was executing and most of the
time the processor was underutilized. During this time, the critical
section was contended 438 times.
The rgb_critical section is the place where the application is
serializing. Each thread has to wait for the critical section to be
available before it can proceed. Only one thread can be in the
critical section at a time. You need to optimize the code to make it
more concurrent.
I was able to follow this tutorial until I reach the next section: Remove the Lock
Remove the Lock
The rgb_critical_section was introduced to protect calculation from
multithreaded access. The brief analysis shows that the code is thread
safe and the critical section is not really needed.
My question is how do we know the code is thread safe?
As suggested I commented those line (EnterCritical... and LeaveCritical...), and saw huge performance gain, but I did not get why this critical section is not required? Which analysis tells us this ?
The relevant code is here in analyze_locks.cpp:
public:
void operator () (const tbb::blocked_range <int> &r) const {
unsigned int serial = 1;
unsigned int mboxsize = sizeof(unsigned int)*(max_objectid() + 20);
unsigned int * local_mbox = (unsigned int *) alloca(mboxsize);
memset(local_mbox,0,mboxsize);
for (int y=r.begin(); y!=r.end(); ++y) {
drawing_area drawing(startx, totaly-y, stopx-startx, 1);
// Enter Critical Section to protect pixel calculation from multithreaded access (Needed?)
// EnterCriticalSection(&rgb_critical_section);
for (int x = startx; x < stopx; x++) {
color_t c = render_one_pixel (x, y, local_mbox, serial, startx, stopx, starty, stopy);
drawing.put_pixel(c);
}
// Exit from the critical section
// LeaveCriticalSection(&rgb_critical_section);
if(!video->next_frame()) tbb::task::self().cancel_group_execution();
}
}
draw_task () {}
};