• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            幾種線程鎖的效率比較(多線程,鎖,CRITICAL_SECTION)

            測試環境Windows XP SP2,Intel Core2 Duo E8400 3.00GHz1.94GB內存

            首先使用CRITICAL_SECTION和自旋機制實現:
            CRITICAL_SECTION GCritical;
            ......
            InitializeCriticalSectionAndSpinCount(&GCritical, 0x80000FA0);
            ......
            //
            線程核心函數,共使用兩個線程
            for (int i = 0; i < 100000000; ++i)
            {
                EnterCriticalSection(&GCritical);
                ++GlobalSum;
                LeaveCriticalSection(&GCritical);
            }
            ......
            DeleteCriticalSection(&GCritical);
            實測時間為21.578s

            使用CRITICAL_SECTION和非自旋機制:
            CRITICAL_SECTION GCritical;
            ......
            InitializeCriticalSection(&GCritical);
            ......
            //
            線程核心函數,共使用兩個線程
            for (int i = 0; i < 100000000; ++i)
            {
                EnterCriticalSection(&GCritical);
                ++GlobalSum;
                LeaveCriticalSection(&GCritical);
            }
            ......
            DeleteCriticalSection(&GCritical);
            運行時間太長,在運行2分鐘后仍然未運行完畢

            可見在大規模并行運算的環境中,如果存在臨界區,自旋鎖的時間開銷遠小于普通的鎖機制。相比于普通鎖,自旋鎖在進入操

            作系統內核態之前會進行多次循環,并在循環中嘗試獲取鎖,如果在循環過程中自旋鎖獲得了鎖則自旋鎖所在線
            程不必由用戶態陷入內核態,也不必交出自己的時間片進入等待狀態(見操作系統原理)。從而大大減少的獲取鎖的時間

            有沒有比自旋鎖開銷更小的鎖機制呢?答案是有,下面就是一個利用X86 Interlock系列指令實現的win32用戶態鎖:
            class CLocker
            {
            private:
            _declspec(align(4)) volatile long m_lThreadId;
            volatile long m_lLockCount;
            int            m_iCollision;

            public:
            CLocker()
               :m_lThreadId(0)
               ,m_lLockCount(0)
               ,m_iCollision(0)
            {}

            ~CLocker()
            {
               if (m_lLockCount > 0)
                __debugbreak();
            }

            void Lock()
            {
               const long tId = ::GetCurrentThreadId();
               if (tId == m_lThreadId)
               {
                ++m_lLockCount;
               }
               else
               {
                int iCol = 0;
                while (true)
                {
                 ++iCol;
                 if (_InterlockedCompareExchange(&m_lThreadId, tId, 0) == 0)
                 {
                  m_lLockCount = 1;
                  if (iCol > m_iCollision)
                   m_iCollision = iCol;
                  return;
                 }

                 //volatile int delay;
                 //const int maxDelay = (int)((rand() / (float)RAND_MAX) * 100) * 50;
                 Sleep(0); //for (delay = 0; delay < maxDelay; ++delay); //
            1
               }
            }

            void Release()
            {
               const long tId = ::GetCurrentThreadId();
               if (tId == m_lThreadId)
               {
                if (--m_lLockCount == 0)
                {
                 //_InterlockedExchange(&m_lThreadId, 0);
                 m_lThreadId = 0;   //
            這里不用Interlock操作,機器字對齊時寫入為原子操作
               }
            }

            int GetCollision()
            {
               return m_iCollision;
            }
            };

            該類通過Interlock系列指令集所具有的原子操作特性互斥的將臨界區資源交給獲得鎖的線程。所有操作均在用戶態執行,邏輯簡單,最終編譯結果指令數也非常少。極大提高了加鎖效率。注1處的循環是一個關鍵點。_InterlockedCompareExchange操作如果失敗會導致CPU執行復雜的Cache操作,從而浪費大量時間。使CAS失敗的線程等待,減少多線程爭用同一鎖時產生過多的_InterlockedCompareExchange操作失敗,從而提高加鎖效率。以下是測試結果

            static CLocker GLocker;
            ......
            //
            線程核心函數,共兩個線程
            for (int i = 0; i < 100000000; ++i)
            {
            GLocker.Lock();
            ++GlobalSum;
            GLocker.Release();
            }
            ......

            測試結果為5.969s,可見用戶態鎖確實具有相對較高的效率。

            需要說明的是,我的本意只是為了探討不同種類鎖的效率,實際情況中,多線程編程要盡量減少多線程間的資源爭用,從設計上避免頻繁加鎖解鎖(Lock-Free算法)

            補充說明,windows平臺和xbox360平臺上的CriticalSection實際上包含一個內存屏障,保證臨界區前后的讀寫操作不會越界執行(見編譯器對指令的優化和CPU的指令亂序執行),一個InterlockedXxx操作,嵌套檢查,滿足特定條件向Mutex操作退化。CriticalSection使用合適的自旋次數能提高效率。CLocker由于沒有內存屏障實際上在某些情況下會不如CriticalSection安全,使用CLocker一定需要程序員自己保證內存操作的順序性。

            實際上臨界區爭用導致線程等待的時間往往大于鎖執行的時間,優化加鎖解鎖速度實際上并未解決根本問題。

            posted on 2011-05-14 02:03 肥仔 閱讀(8114) 評論(1)  編輯 收藏 引用 所屬分類: Windows開發

            評論

            # re: 幾種線程鎖的效率比較(多線程,鎖,CRITICAL_SECTION)  回復  更多評論   

            I greatly appreciate your thoughts. For me these are significant things. Anyhow appreciate it. Good look over.
            2011-05-14 14:52 | parker pen
            欧美午夜精品久久久久久浪潮| 超级碰碰碰碰97久久久久| 99热成人精品热久久669| 99久久免费国产精精品| 国产精品欧美久久久久无广告| 久久夜色撩人精品国产| 久久综合香蕉国产蜜臀AV| 久久精品国产一区二区三区日韩| 91久久精品国产91性色也| 国内精品伊人久久久久777| 久久er国产精品免费观看2| 久久人人爽人人爽人人片AV不| 国产精品视频久久久| 久久人人添人人爽添人人片牛牛| 97久久超碰国产精品2021| 久久久这里有精品| 88久久精品无码一区二区毛片| 精品国产乱码久久久久久人妻| 伊人久久精品线影院| 人妻无码αv中文字幕久久琪琪布| 久久se精品一区二区影院 | 久久亚洲国产成人影院网站| 亚洲精品高清国产一线久久| 久久精品国产精品亚洲艾草网美妙| 色欲av伊人久久大香线蕉影院| 久久人人爽人人爽AV片| 久久青草国产精品一区| 久久综合精品国产二区无码| 区久久AAA片69亚洲| 亚洲精品97久久中文字幕无码| 精品久久久久久无码中文野结衣 | 亚洲欧美精品伊人久久| 伊人久久大香线焦AV综合影院 | 粉嫩小泬无遮挡久久久久久| 久久久久国产精品嫩草影院| 午夜福利91久久福利| 久久免费观看视频| 亚洲人AV永久一区二区三区久久| 久久久久国产日韩精品网站| 欧美久久综合九色综合| 久久久久噜噜噜亚洲熟女综合|