लोड से जुड़े/स्टोर अनन्य प्रतिमान के पीछे विचार यह है कि अगर अगर दुकान लोड के बाद बहुत जल्द ही, कोई हस्तक्षेप स्मृति कार्यों के साथ, और इस प्रकार अगर और कुछ नहीं स्थान को छुआ है, दुकान है संभवतः सफल होने के लिए, लेकिन यदि कुछ और स्थान को छुआ है तो स्टोर कुछ विफल होने के लिए है। इस बात की कोई गारंटी नहीं है कि स्टोर कभी-कभी किसी स्पष्ट कारण के लिए विफल नहीं होंगे;
do
{
new_value = __LDREXW(dest) + 1;
} while (__STREXW(new_value, dest));
आम तौर पर भरोसा किया जा सकता कुछ प्रयास के भीतर सफल होने के लिए: अगर लोड और दुकान के बीच का समय कम से कम रखा है, तथापि, और वहाँ कोई स्मृति एक पाश की तरह उन दोनों के बीच पहुंचता है, तो कर रहे हैं।यदि कंप्यूटिंग वर्ष मूल्य के आधार पर नया मान कुछ महत्वपूर्ण गणना की आवश्यकता है, एक पाश को फिर से लिखने चाहिए के रूप में:
do
{
old_value = *dest;
new_value = complicated_function(old_value);
} while (CompareAndStore(dest, new_value, old_value) != 0);
... Assuming CompareAndStore is something like:
uint32_t CompareAndStore(uint32_t *dest, uint32_t new_value, uint_32 old_value)
{
do
{
if (__LDREXW(dest) != old_value) return 1; // Failure
} while(__STREXW(new_value, dest);
return 0;
}
इस कोड को अपने मुख्य पाश * गंतव्य को फिर से चलाएं करने के लिए अगर कुछ बदल जाता है, जबकि नए मूल्य का अभिकलन किया जा रहा है होगा है, लेकिन केवल छोटे पाश को फिर से चलाएं जा सकता है अगर __STREXW किसी अन्य कारण से विफल रहता है [जो उम्मीद है कि बहुत संभावना नहीं है, यह देखते हुए कि वहाँ केवल __LDREXW और __STREXW के बीच के बारे में दो निर्देश दिए जाएंगे कि] की आवश्यकता होगी
परिशिष्ट ऐसी परिस्थिति का एक उदाहरण जहां "पुराने पर आधारित नए मूल्य की गणना करें" जटिल हो सकता है, जहां "मान" ar होगा ई प्रभावी रूप से एक जटिल डेटा संरचना के संदर्भ। कोड पुराना संदर्भ प्राप्त कर सकता है, पुराने से एक नई डेटा संरचना प्राप्त कर सकता है, और उसके बाद संदर्भ अद्यतन कर सकते हैं। यह पैटर्न "नंगे धातु" प्रोग्रामिंग की तुलना में कचरे से एकत्रित ढांचे में अधिक बार आता है, लेकिन प्रोग्रामिंग नंगे धातु के दौरान भी कई तरह के तरीके सामने आ सकते हैं। सामान्य मॉलोक/कॉलोक आवंटक आमतौर पर थ्रेड-सुरक्षित/इंटरप्ट-सुरक्षित नहीं होते हैं, लेकिन निश्चित आकार संरचनाओं के लिए आवंटक अक्सर होते हैं। एक एक कुछ सत्ता के-दो डेटा संरचनाओं की संख्या का "पूल" है (255 कहते हैं), एक तरह कुछ इस्तेमाल कर सकते हैं:
#define FOO_POOL_SIZE_SHIFT 8
#define FOO_POOL_SIZE (1 << FOO_POOL_SIZE_SHIFT)
#define FOO_POOL_SIZE_MASK (FOO_POOL_SIZE-1)
void do_update(void)
{
// The foo_pool_alloc() method should return a slot number in the lower bits and
// some sort of counter value in the upper bits so that once some particular
// uint32_t value is returned, that same value will not be returned again unless
// there are at least (UINT_MAX)/(FOO_POOL_SIZE) intervening allocations (to avoid
// the possibility that while one task is performing its update, a second task
// changes the thing to a new one and releases the old one, and a third task gets
// given the newly-freed item and changes the thing to that, such that from the
// point of view of the first task, the thing never changed.)
uint32_t new_thing = foo_pool_alloc();
uint32_t old_thing;
do
{
// Capture old reference
old_thing = foo_current_thing;
// Compute new thing based on old one
update_thing(&foo_pool[new_thing & FOO_POOL_SIZE_MASK],
&foo_pool[old_thing & FOO_POOL_SIZE_MASK);
} while(CompareAndSwap(&foo_current_thing, new_thing, old_thing) != 0);
foo_pool_free(old_thing);
}
अगर वहाँ अक्सर एक से अधिक थ्रेड/बीच में आता है/जो कुछ भी करने की कोशिश कर नहीं होगा एक ही समय में एक ही चीज़ को अपडेट करें, इस दृष्टिकोण को अद्यतनों को सुरक्षित रूप से निष्पादित करने की अनुमति देनी चाहिए। यदि उन चीजों में प्राथमिकता संबंध मौजूद होगा जो एक ही आइटम को अद्यतन करने का प्रयास कर सकते हैं, तो सर्वोच्च प्राथमिकता वाले को अपने पहले प्रयास में सफल होने की गारंटी दी जाती है, अगली उच्चतम प्राथमिकता किसी भी प्रयास पर सफल होगी जिसे पूर्ववत नहीं किया जाता है उच्चतम प्राथमिकता वाला एक, आदि। यदि कोई लॉकिंग का उपयोग कर रहा था, तो उच्चतम प्राथमिकता वाले कार्य जो अद्यतन करना चाहते थे, को निम्न प्राथमिकता अद्यतन को समाप्त करने की प्रतीक्षा करनी होगी; तुलना और स्नैप प्रतिमान का उपयोग करके, उच्चतम प्राथमिकता कार्य निचले हिस्से से अप्रभावित होगा (लेकिन निचले व्यक्ति को बर्बाद काम करना होगा)।
मैं वही काम कर रहा हूं लेकिन वह हिस्सा जहां नए मूल्य के लिए महत्वपूर्ण कंप्यूटिंग की आवश्यकता है, मुझे अभी भी पहेली। Cmxchg लूप का उपयोग करना समझ में आता है क्योंकि तब विशेष मॉनिटर को एक संदर्भ स्विच द्वारा साफ़ नहीं किया जाएगा, लेकिन महत्वपूर्ण कंप्यूटिंग को फिर से करने के लिए बहुत अधिक ओवरहेड की आवश्यकता होती है क्योंकि मैंने सड़क को बिना किसी स्पष्ट कारणों से विफल करने के लिए देखा है (पीएसआर में आईआरक्यू के साथ यूपी) जैसा कि आपकी पोस्ट में उल्लिखित है। – sgupta
@ user1075375: इन्हें देखें – supercat
ये (__LDREXW और __STREXW) कोर्टेक्स-एम श्रृंखला माइक्रोक्रोनरोलर-स्तरीय प्रोसेसर के लिए केइल कंपाइलर्स में समर्थित इंट्रिनिक्स हैं, जो आम तौर पर मुख्यधारा के एआरएम लक्ष्यों (उदाहरण के लिए, एएआरएच 64) और कंपाइलर्स (उदाहरण के लिए, जीसीसी, एलएलवीएम) के लिए उपलब्ध नहीं हैं।) सही? http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABDEEJC.html – ahcox