2012-03-15 10 views
10

पर पढ़ा गया है, मुझे परमाणु रूप से 16 बाइट पढ़ने/लिखने की आवश्यकता है। मैं केवल cmpxchg16 का उपयोग करके लेखन करता हूं, जो सभी x64 प्रोसेसर पर उपलब्ध है, सिवाय इसके कि मैं एक अस्पष्ट एएमडी के लिए सोचता हूं।परमाणु 16 बाइट x64 CPUs

अब प्रश्न 16 बाइट मानों को गठबंधन करने के लिए है, केवल cmpxchg16 (जो पूर्ण मेमोरी बाधा की तरह कार्य करता है) का उपयोग करके कभी संशोधित किया गया है, क्या यह 16 बाइट स्थान पढ़ने के लिए संभव है जो आधा पुराना डेटा और आधा नया डेटा है?

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

मैं इस धारणा को बना रहा हूं कि जब cmpxchg16 निष्पादित किया जाता है, तो यह 16 बाइटों को परमाणु रूप से संशोधित करता है, न कि अन्य थ्रेडों के बीच पढ़ने के लिए दो 8 बाइट ब्लॉक लिखकर (ईमानदारी से मैं नहीं देखता कि यह कैसे काम कर सकता है अगर यह परमाणु नहीं था।)

क्या मैं सही हूँ? यदि मैं गलत हूं, तो क्या लॉकिंग का उपयोग किए बिना परमाणु 16 बाइट पढ़ने का कोई तरीका है?

नोट: couple similar questions here हैं लेकिन वे उस मामले से निपटते नहीं हैं जहां लेखन केवल cmpxchg16 के साथ किया जाता है, इसलिए मुझे लगता है कि यह एक अलग, अनुत्तरित प्रश्न है।

संपादित करें: असल में मुझे लगता है कि मेरा तर्क दोषपूर्ण था। एक एसएसई लोड निर्देश दो 64 बिट पढ़ने के रूप में निष्पादित किया जा सकता है, और cmpxchg16 को दूसरे प्रोसेसर द्वारा दो पढ़ने के बीच निष्पादित किया जा सकता है।

+1

के रूप में सरल कुछ करने के लिए मूल्यांकन करता है यानी वे परमाणु नहीं हैं। इससे कोई फर्क नहीं पड़ता कि आपके लेखन परमाणु रूप से CMPXCHG16B के साथ किया जाता है। पढ़ना भी परमाणु होना चाहिए या आप असंगत डेटा देख सकते हैं। AFAIK आपकी एकमात्र पसंद सीएमपीएक्सएचजी 16 बी के साथ पढ़ना है। – Timo

+0

ये, मैंने सोचने की गलती की है कि मुझे केवल धागे को पढ़ने के बीच बाधित होने से रोकना है, लेकिन असली बस संचालन अभी भी अंतःस्थापित हो सकता है। – Eloff

+0

पढ़ने पर cmpxchg16b का उपयोग करके उन्हें अस्वीकार्य रूप से धीमा कर दिया जाएगा। लेकिन 25% अधिक मेमोरी का उपयोग करके मैं दिमित्री व्याकोव के हैशैप जैसे सीक्लॉक स्टाइल दृष्टिकोण कर सकता हूं: http://www.1024cores.net/home/downloads – Eloff

उत्तर

9
typedef struct 
{ 
    unsigned __int128 value; 
} __attribute__ ((aligned (16))) atomic_uint128; 

unsigned __int128 
atomic_read_uint128 (atomic_uint128 *src) 
{ 
    unsigned __int128 result; 
    asm volatile ("xor %%rax, %%rax;" 
       "xor %%rbx, %%rbx;" 
       "xor %%rcx, %%rcx;" 
       "xor %%rdx, %%rdx;" 
       "lock cmpxchg16b %1" : "=A"(result) : "m"(*src) : "rbx", "rcx"); 
    return result; 
} 

यह चाल चलाना चाहिए। टाइपपीफ सही संरेखण सुनिश्चित करता है। cmpxchg16b को 16 बाइट सीमा पर गिनने के लिए डेटा की आवश्यकता है।

cmpxchg16b परीक्षण करेगा यदि *src शून्य है और शून्य (एनओपी) शून्य हो। किसी भी मामले में सही मूल्य आरएक्स में खड़ा होगा: आरडीएक्स बाद में।

ऊपर कोड यह पहले से ही जुड़ा हुआ प्रश्न का उत्तर था कि 16-बाइट SSE पढ़ता कई स्मृति तक पहुँचता है के साथ लागू किया जा सकता है,

push %rbx 
xor %rax,%rax 
xor %rbx,%rbx 
xor %rcx,%rcx 
xor %rdx,%rdx 
lock cmpxchg16b (%rdi) 
pop %rbx 
retq 
+0

हां, मुझे लगता है कि यह करने का तरीका होना चाहिए।यह अब मेरे लिए होता है कि एक साधारण एसएसई लोड को दो 64 बिट पढ़ने में विभाजित किया जा सकता है और cmpxchg16 संभावित रूप से पढ़ने के बीच हो सकता है। – Eloff

1

संदर्भ के अनुसार http://siyobik.info/main/reference/instruction/CMPXCHG8B%2FCMPXCHG16BCMPXCHG16 डिफ़ॉल्ट परमाणु द्वारा नहीं है, लेकिन इसका मतलब है कि डिफ़ॉल्ट रूप से, डेटा पढ़ने के भीतर बदला जा सकता है और चरणों लिखने LOCKhttp://siyobik.info/main/reference/instruction/LOCK

का उपयोग करके परमाणु बनाया जा सकता है। लॉकिंग दोनों पढ़ने और लिखने परमाणु बनाता है।

+0

"ध्यान दें कि सीएमपीएक्सएचजी 16 बी के लिए आवश्यक है कि गंतव्य (मेमोरी) ऑपरेंड 16-बाइट गठबंधन हो । " – kay

+0

क्षमा करें, हाँ मेरा मतलब लॉक उपसर्ग के साथ cmpxchg16 था। लेकिन लॉक एसएसई निर्देशों के साथ इस्तेमाल नहीं किया जा सकता है। – Eloff

संबंधित मुद्दे