कैसे कर सकते हैं std :: lock_guard std से तेज हो :: mutex :: lock ()?


9

मैं एक सहकर्मी के साथ बहस कर रहा था, लॉक_गार्ड के बारे में, और उसने प्रस्ताव दिया कि इंस्टेंट की लागत के कारण लॉक_गार्ड म्यूटेक्स की तुलना में बहुत धीमा है।

तब मैंने यह सरल परीक्षण बनाया और, आश्चर्य की बात यह है कि लॉक_गार्ड वाला संस्करण म्यूटेक्स :: लॉक () / म्यूटेक्स :: अनलॉक () के साथ संस्करण की तुलना में लगभग दो गुना तेज है।

#include <iostream>
#include <mutex>
#include <chrono>

std::mutex m;
int g = 0;

void func1()
{
    m.lock();
    g++;
    m.unlock();
}

void func2()
{
    std::lock_guard<std::mutex> lock(m);
    g++;
}

int main()
{
    auto t = std::chrono::system_clock::now();
    for (int i = 0; i < 1000000; i++)
    {
        func1();
    }

    std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;

    t = std::chrono::system_clock::now();
    for (int i = 0; i < 1000000; i++)
    {
        func2();
    }

    std::cout << "Take: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count() << " ms" << std::endl;

    return 0;
}

मेरी मशीन पर परिणाम:

Take: 41 ms
Take: 22 ms

क्या कोई स्पष्ट कर सकता है कि यह क्यों और कैसे हो सकता है?


2
और आपने कितनी बार अपना माप लिया?
आर्टम

7
कृपया अपने संकलक झंडे को पोस्ट करें ... बेंचमार्किंग अनुकूलन स्तर पर निर्भर करेगा ...
मैकडेम

10
प्रो टिप: इस तरह से माप करते समय, यह सुनिश्चित करने के लिए आदेश स्वैप करें कि यह केवल ठंडा डेटा / निर्देश नहीं है, जिससे समस्या उत्पन्न हो रही है: coliru.stacked-croched.com/a/81f75a1ab52cb1cc
NathanOverver

2
इस तरह से माप करते समय एक और चीज सहायक होती है: पूरी चीज को एक बड़े लूप में रखें, ताकि आप पूरे माप सेट को चलाएं, कहें कि प्रत्येक बार 20 बार दौड़ें। आमतौर पर बाद के माप वे होंगे जो वास्तव में सार्थक होते हैं, क्योंकि तब तक कैश लंबे समय तक चलने वाले व्यवहार में बस गया है।
मार्क फ्रेड्रस

2
यहां तक ​​कि अगर std::lock_guardथोड़ा धीमा था, जब तक कि आप यह साबित नहीं कर सकते कि यह प्रदर्शन के मामले में मायने रखता है, तो गति का लाभ उपयोग के अन्य लाभों std::lock_guard(मुख्य रूप से RAII) को अमान्य नहीं करेगा । यदि g++ऐसा कुछ है जो फेंक सकता है या ऐसा कुछ भी हो सकता है जो भविष्य में संभावित रूप से अधिक जटिल हो सकता है तो आपको लॉक के मालिक के लिए किसी प्रकार की वस्तु का उपयोग करना होगा।
फ्राँस्वा एंड्रीक्स

जवाबों:


6

रिलीज़ बिल्ड दोनों संस्करणों के लिए समान परिणाम तैयार करता है।

DEBUGनिर्माण शो के लिए ~ 33% लंबे समय func2; अंतर जो मैं disassembly में देखता हूं जो func2उपयोग करता है __security_cookieऔर आक्रमण करता है @_RTC_CheckStackVars@8

क्या आप DEBUG का समय निकाल रहे हैं?

संपादित करें: इसके अतिरिक्त, RELEASEडिस्सैम्फ़ड को देखते हुए, मैंने देखा कि mutexदो रजिस्ट्रियों में तरीकों को सहेजा गया था:

010F104E  mov         edi,dword ptr [__imp___Mtx_lock (010F3060h)]  
010F1054  xor         esi,esi  
010F1056  mov         ebx,dword ptr [__imp___Mtx_unlock (010F3054h)]  

और दोनों से एक ही तरह से कहा जाता है func1और func2:

010F1067  call        edi  
....
010F107F  call        ebx  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.