我正在关注本教程以了解如何使用 VTUNE 删除锁
此页面在收集 Vtune 结果后显示以下内容:
识别最热门的代码行
单击热点导航按钮转到等待时间最长的代码行。VTune Amplifier 突出显示进入 draw_task 函数中临界区 rgb_critical_section 的第 170 行。draw_task 函数在此代码行执行期间等待了将近 27 秒,并且大部分时间处理器未得到充分利用。在此期间,临界区被争用了 438 次。
rgb_critical 部分是应用程序序列化的地方。每个线程必须等待关键部分可用才能继续。一次只能有一个线程位于临界区。您需要优化代码以使其更具并发性。
在我到达下一部分之前,我能够按照本教程进行操作:移除锁
取下锁
引入 rgb_critical_section 是为了保护计算免受多线程访问。简要分析表明,代码是线程安全的,临界区并不是真正需要的。
我的问题是我们怎么知道代码是线程安全的?
正如建议的那样,我评论了那些行(EnterCritical ...和LeaveCritical ...),并看到了巨大的性能提升,但我不明白为什么不需要这个关键部分?哪项分析告诉我们这一点?
相关代码在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 () {}
};