2009-07-18 13 views
8

के बराबर समकक्ष मैं LWARX और STWCX (जैसा कि पावरपीसी प्रोसेसर पर पाया गया है) या x86 प्लेटफॉर्म पर समान कार्यक्षमता को लागू करने का एक तरीका ढूंढ रहा हूं। साथ ही, ऐसी चीजों के बारे में जानने के लिए सबसे अच्छी जगह कहां होगी (यानी लॉक/प्रतीक्षा-मुक्त प्रोग्रामिंग के लिए अच्छे लेख/वेब साइट/फ़ोरम)।x86 LWARX और STWCX


संपादित
मैं मुझे लगता है कि मैं सिर्फ एक कैस के लिए देख रहा हूँ (तुलना और स्वैप) आपरेशन के रूप में यह मान लिया जा रहा है और अधिक जानकारी देने के लिए आवश्यकता हो सकती है लगता है। जो मैं करने की कोशिश कर रहा हूं वह स्मार्ट पॉइंटर्स के साथ लॉक-फ्री संदर्भ गिनती प्रणाली को कार्यान्वित कर रहा है जिसे एकाधिक थ्रेडों द्वारा एक्सेस और बदला जा सकता है। मुझे मूल रूप से x86 प्रोसेसर पर निम्न फ़ंक्शन को लागू करने का एक तरीका चाहिए।

int* IncrementAndRetrieve(int **ptr) 
{ 
    int val; 
    int *pval; 
    do 
    { 
    // fetch the pointer to the value 
    pval = *ptr; 

    // if its NULL, then just return NULL, the smart pointer 
    // will then become NULL as well 
    if(pval == NULL) 
     return NULL; 

    // Grab the reference count 
    val = lwarx(pval); 

    // make sure the pointer we grabbed the value from 
    // is still the same one referred to by 'ptr' 
    if(pval != *ptr) 
     continue; 

    // Increment the reference count via 'stwcx' if any other threads 
    // have done anything that could potentially break then it should 
    // fail and try again 
    } while(!stwcx(pval, val + 1)); 
    return pval; 
} 

मैं वास्तव में कुछ है कि नकल करता LWARX और STWCX अच्छी तरह सटीक इस बंद को खींचने के लिए (मैं CompareExchange, स्वैप के साथ ऐसा कर या कार्यों मैं अब तक के लिए मिल गया है डालने का एक तरीका को समझ नहीं सकता की जरूरत है x86)।

धन्यवाद

उत्तर

11

जैसा कि माइकल ने उल्लेख किया है, आप शायद जो देख रहे हैं वह cmpxchg निर्देश है।

यह इंगित करना महत्वपूर्ण है कि इसे पूरा करने की पीपीसी विधि Load Link/Store Conditional (एलएल/एससी) के रूप में जानी जाती है, जबकि x86 आर्किटेक्चर Compare And Swap (सीएएस) का उपयोग करता है। एलएल/एससी में सीएएस की तुलना में मजबूत अर्थशास्त्र है कि कंडीशन किए गए पते पर मूल्य में किए गए किसी भी बदलाव से दुकान विफल हो जाएगी, भले ही अन्य परिवर्तन मूल्य को उस मूल्य के साथ बदल देता है जिस पर लोड की स्थिति थी। दूसरी ओर, सीएएस इस मामले में सफल होगा। इसे एबीए समस्या के रूप में जाना जाता है (अधिक जानकारी के लिए सीएएस लिंक देखें)।

आप x86 आर्किटेक्चर पर मजबूत अर्थ विज्ञान की जरूरत है, तो आप इसे x86s दोहरी-चौड़ाई की तुलना और स्वैप (DWCAS) अनुदेश cmpxchg8b, या x86_64 के तहत cmpxchg16b का उपयोग करके अनुमान लगा सकता है। यह आपको सामान्य रूप से सामान्य की बजाय, लगातार दो लगातार 'प्राकृतिक आकार' शब्दों को स्वैप करने की अनुमति देता है। मूल विचार दो शब्दों में से एक है जिसमें ब्याज का मूल्य होता है, और दूसरे में हमेशा 'उत्परिवर्तन गिनती' होती है। यद्यपि यह तकनीकी रूप से समस्या को खत्म नहीं करता है, लेकिन उत्परिवर्तन काउंटर की संभावनाओं के बीच लपेटने की संभावना इतनी कम है कि यह अधिकांश उद्देश्यों के लिए एक उचित विकल्प है।

+0

डीसीएएस लगभग सही दिखता है, सिवाय इसके कि मैं ऐसा करने के लिए केवल 1 शब्द बदलने की आवश्यकता है यदि ऐसा करने के दौरान उस शब्द का सूचक बदल नहीं जाता है (यह थोड़ा उलझन में है, उम्मीद है कि प्रश्न का अद्यतन इसे स्पष्ट करने में मदद करता है)। –

+0

मैं डीसीएएस का उपयोग करके एक वर्कअराउंड खोजने में कामयाब रहा, यह मूर्खतापूर्ण नहीं है, क्योंकि यह एक अद्वितीय आईडी (आकार में 4 बाइट्स) का उपयोग करता है लेकिन इसे तोड़ने की संभावनाएं पतली हैं क्योंकि 4 बाइट यूआईडी और 4 बाइट काउंटर दोनों इसके समीप होंगे बिल्कुल दोहराया गया। यह केवल एक समस्या है यदि वस्तु किसी चीज को स्मृति को फिर से सौंपती है और फिर उन 8 बाइट्स को डुप्लिकेट करने का प्रबंधन करती है, जबकि दूसरा धागा एक सूचक की प्रतिलिपि बनाने का प्रयास कर रहा है, जो एक अपेक्षाकृत छोटा ऑपरेशन है (ऑपरेशन के अनुसार, लंबाई केवल लंबी है थ्रेड बाधित होने पर पर्याप्त है) –

+0

मुझे विशेष रूप से पीपीसी के बारे में पता नहीं है, लेकिन अधिकांश मशीनों पर, लोड-एक्सक्लूसिव/स्टोर-सशर्त निर्देश वास्तव में एबीए समस्या से मदद नहीं करते हैं क्योंकि लोड-अनन्य के बीच मेमोरी ऑपरेशंस और स्टोर-सशर्त स्टोर स्टोर सशर्त ऑपरेशन को असफल रूप से विफल कर सकता है। यदि कोई संरक्षित स्थान को दोबारा पढ़ता है और देखता है कि यह बदल गया है, तो कोई यह बता सकता है कि किसी और ने इसे एक नए मूल्य के साथ लिखा है, लेकिन यदि पिछले पाठ के समान मूल्य है, तो एक सहज विफलता को अलग करने का कोई तरीका नहीं होगा एक एबीए लिखो। – supercat

2

86 सीधे "आशावादी संगामिति" का समर्थन नहीं करता पीपीसी करता है - बल्कि, संगामिति के लिए 86 के समर्थन के लिए एक "ताला उपसर्ग" पर आधारित है, here देखते हैं। (एक्सएचजीजी जैसे कुछ तथाकथित "परमाणु" निर्देश वास्तव में LOCK उपसर्ग को जोर देकर अपने परमाणुता प्राप्त करते हैं, चाहे असेंबली कोड प्रोग्रामर ने वास्तव में इसे कोड किया हो या नहीं)। यह वास्तव में "बम-सबूत" नहीं है, इसे राजनयिक रूप से डालने के लिए (वास्तव में, यह दुर्घटनाग्रस्त है, मैं कहूंगा ;-)।

1

आप शायद निर्देशों के cmpxchg परिवार की तलाश में हैं।

समकक्ष व्यवहार प्राप्त करने के लिए आपको लॉक निर्देश के साथ इन्हें पहले से करना होगा।

क्या उपलब्ध है इसके त्वरित विवरण के लिए here पर एक नज़र डालें।

आप की संभावना इस के समान कुछ के साथ खत्म हो जाएगा:

mov ecx,dword ptr [esp+4] 
mov edx,dword ptr [esp+8] 
mov eax,dword ptr [esp+12] 
lock cmpxchg dword ptr [ecx],edx 
ret 12 

आप this paper पढ़ना चाहिए ...

संपादित

अद्यतन प्रश्न के उत्तर में, आप कर रहे हैं Boost shared_ptr जैसे कुछ करने की तलाश में? यदि ऐसा है, तो उस कोड और उस निर्देशिका में फ़ाइलों को देखें - वे निश्चित रूप से आपको शुरू कर देंगे।

+0

वे 2 लिंक काफी अच्छे हैं (वास्तव में कुछ दिनों पहले उन 2 पृष्ठों में ठोकर खाए गए थे), लेकिन दुर्भाग्यवश जो मैं खोज रहा हूं (मैंने इसे बेहतर ढंग से प्रतिबिंबित करने के लिए प्रश्न अपडेट किया) –

0

जो आप करने की कोशिश कर रहे हैं वह आपके द्वारा अपेक्षित तरीके से काम नहीं करेगा। आपने जो कार्यान्वित किया है वह इंटरलाक्ड इंस्ट्रक्शन फ़ंक्शन (Win32 फ़ंक्शन; असेंबली: एक्सएडीडी) के साथ किया जा सकता है।

कारण यह है कि आपका कोड ऐसा नहीं करता है जो आपको लगता है कि यह एक और धागा अभी भी stwcx को अमान्य किए बिना * ptr और stwcx के दूसरे पढ़ने के बीच मान को बदल सकता है।

+0

"अगर (पावल! = पीआरटी) जारी है;" सुरक्षित है क्योंकि जब भी कोई अन्य धागा एक स्मार्ट सूचक बदलता है, तो यह उस काउंटर को भी बदल देगा जो इसकी ओर इशारा करता है, इसलिए, यह stwcx को अमान्य कर देगा क्योंकि यह मान बदल जाता है, और परिवर्तन के लिए निगरानी की जा रही है (केवल कुछ सावधानीपूर्वक संरचना की आवश्यकता है) –

+0

आपको वास्तव में दूसरी तरफ भी पोस्ट करना होगा। मैंने अभी एक जवाब बनाने की कोशिश की लेकिन इसमें बहुत अधिक अनुमान लगाया गया। आम तौर पर, सीएएस का उपयोग करके इन प्रकार की समस्याओं का हल किया जा सकता है। – Ringding

0

यदि आप 64 बिट्स पर हैं और खुद को 1 टीबी ढेर कहने के लिए सीमित करते हैं, तो आप काउंटर को 24 अप्रयुक्त शीर्ष बिट्स में पैक कर सकते हैं। यदि आपके पास गठबंधन पॉइंटर्स शब्द हैं तो नीचे 5 बिट भी उपलब्ध हैं। यदि LWARX और STWCX पूरे कैश लाइन को अमान्य

int* IncrementAndRetrieve(int **ptr) 
{ 
    int val; 
    int *unpacked; 
    do 
    { 
    val = *ptr; 
    unpacked = unpack(val); 

    if(unpacked == NULL) 
     return NULL; 
    // pointer is on the bottom 
    } while(!cas(unpacked, val, val + 1)); 
    return unpacked; 
} 
+0

मेमोरी को सबसे कम ढेर पर आवंटित नहीं किया जाना चाहिए, इसलिए आप इस बारे में सुनिश्चित नहीं हो सकते हैं, जब तक कि आप स्वयं को पते निर्दिष्ट नहीं कर रहे हैं (दुर्भाग्यवश, मैं 64-बिट प्लेटफ़ॉर्म पर नहीं हूं , लेकिन यह भविष्य में उपयोगी हो सकता है। –

0

पता नहीं है, कैस और DCAS है। इसका मतलब यह है कि जब तक आप बहुत सारी मेमोरी (प्रत्येक स्वतंत्र "लॉक करने योग्य" पॉइंटर के लिए 64 बाइट्स) फेंकने के इच्छुक नहीं हैं, तो आप वास्तव में तनाव में अपने सॉफ़्टवेयर को दबा रहे हैं तो आपको अधिक सुधार दिखाई नहीं देगा। अब तक के सबसे अच्छे परिणाम मैंने देखा है जब लोगों ने जानबूझकर 64 बी का अपमान किया था, इसके चारों ओर अपनी संरचनाओं की योजना बनाई थी (सामान पैक करना जो विवाद का विषय नहीं होगा), 64b सीमाओं पर सब कुछ गठबंधन रखा गया था, और डेटा बाधाओं को स्पष्ट रूप से पढ़ और लिखने के लिए इस्तेमाल किया गया था। कैश लाइन अमान्यता लगभग 20 से 100 चक्रों का खर्च ले सकती है, जिससे इसे एक बड़ा वास्तविक perf मुद्दा बना दिया जाता है, फिर केवल टालना बंद कर दें।

इसके अलावा, आपको नियंत्रित लीकिंग को प्रबंधित करने के लिए अलग-अलग स्मृति आवंटन रणनीति की योजना बनाना होगा (यदि आप तार्किक "अनुरोध प्रसंस्करण" में कोड विभाजित कर सकते हैं - एक अनुरोध "लीक" - और अंत में इसके सभी मेमोरी थोक को रिलीज़ करता है) या आवंटित आवंटन प्रबंधन ताकि सामग्री के तहत एक संरचना को उसी संरचना/संग्रह (एबीए को रोकने के लिए) के तत्वों द्वारा वास्तविक स्मृति प्राप्त न हो। उनमें से कुछ बहुत ही अंतर्ज्ञानी हो सकते हैं लेकिन यह या तो जीसी के लिए कीमत चुका रहा है।

+0

हाँ, यह इन दिनों एक गैर-मुद्दा है, अंत में मैंने कंपनी के बाकी कोडर को और अधिक मैन्युअल प्रबंधन और प्रशिक्षण देने का विकल्प चुना है जो कि कुछ लॉक मुक्त संरचनाओं के माध्यम से बहु-थ्रेडिंग को सही तरीके से कैसे करें अंतर धागा संचार। –