简体   繁体   English

我们怎么知道代码是线程安全的?

[英]How do we know that the code is thread safe?

I am following this tutorial to understand how to remove locks , using VTUNE 我正在按照本教程了解如何使用VTUNE删除锁
This page says the following after collecting Vtune results: 收集Vtune结果后,该页面显示以下内容:

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. VTune放大器突出显示在draw_task函数中进入关键部分rgb_critical_section的行170。 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. 在执行此代码行时,draw_task函数等待了将近27秒,并且在大多数情况下未充分利用处理器。 During this time, the critical section was contended 438 times. 在此期间,关键部分被竞争438次。

The rgb_critical section is the place where the application is serializing. rgb_critical部分是应用程序进行序列化的地方。 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. 引入了rgb_critical_section以保护计算免受多线程访问。 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? 如建议的那样,我评论了这些行(EnterCritical ...和LeaveCritical ...),并看到了巨大的性能提升,但是我不明白为什么不需要此关键部分? Which analysis tells us this ? 哪个分析告诉我们这一点?

The relevant code is here in analyze_locks.cpp: 相关代码在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 () {}

};

Something is threadsafe if no global state (that is, state outside of this particular thread) is being modified. 如果未修改全局状态(即,该特定线程之外的状态),则某些事情是线程安全的。 It's hard for us to tell what render_one_pixel and drawing.put_pixel actually does, and in what order it may need to be performed. 我们很难说出render_one_pixeldrawing.put_pixel实际作用,以及可能需要按照什么顺序执行。

Assuming that the order of the calls to put_pixel(c) doesn't matter (or which thread makes the call), it would be safe to remove the critical section here. 假设对put_pixel(c)的调用顺序无关紧要(或由哪个线程进行调用),则可以安全地删除此处的关键部分。 If there is strict ordering required, I'm not sure a critical section is the right solution anyway. 如果需要严格的订购,那么我不确定关键部分是否是正确的解决方案。 (The same rules obviouysly apply to render_one_pixel , if it changes some global state, which would of course also have to be taken into account in the "is it safe"). (同样的规则显然适用于render_one_pixel ,如果它更改了某些全局状态,则当然必须在“是否安全”中加以考虑)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM