2012-02-15 18 views
13

में परमाणु संचालन कार्यान्वयन को पढ़ें और लिखें हाल ही में मैंने एक परमाणु पढ़ने और लिखने के लिनक्स कर्नेल कार्यान्वयन में देखा है और कुछ प्रश्न उठ गए हैं।लिनक्स कर्नेल

पहले ia64 वास्तुकला से प्रासंगिक कोड:

typedef struct { 
    int counter; 
} atomic_t; 

#define atomic_read(v)  (*(volatile int *)&(v)->counter) 
#define atomic64_read(v) (*(volatile long *)&(v)->counter) 

#define atomic_set(v,i)  (((v)->counter) = (i)) 
#define atomic64_set(v,i) (((v)->counter) = (i)) 
  1. दोनों पढ़ने और लिखने के संचालन के लिए, ऐसा लगता है कि प्रत्यक्ष दृष्टिकोण से पढ़ने के लिए या चर करने के लिए लिखने के लिए ले जाया गया। जब तक कोई और चाल नहीं है, मुझे समझ में नहीं आता कि गारंटी क्या है कि यह ऑपरेशन असेंबली डोमेन में परमाणु होगा। मुझे लगता है कि एक स्पष्ट उत्तर यह होगा कि ऐसा ऑपरेशन एक असेंबली ओपोड में अनुवाद करता है, लेकिन फिर भी, विभिन्न स्मृति कैश स्तर (या अन्य अनुकूलन) को ध्यान में रखते समय यह गारंटी कैसे दी जाती है?

  2. पढ़ने मैक्रोज़ पर, अस्थिर प्रकार कास्टिंग कास्टिंग में उपयोग किया जाता है। किसी के पास एक सुराग है कि यह परमाणुता को कैसे प्रभावित करता है? (ध्यान दें कि इसका उपयोग लेखन ऑपरेशन में नहीं किया जाता है)

उत्तर

13

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

"परमाणु" और "अस्थिर" शब्द का अर्थ यह नहीं है कि स्मृति सिंक्रनाइज़ेशन का कोई भी रूप है। न तो किसी भी पढ़ने/लिखने बाधाओं या बाड़ का तात्पर्य है। स्मृति और कैश समेकन के संबंध में कुछ भी गारंटी नहीं है।ये फ़ंक्शंस केवल मूल रूप से सॉफ़्टवेयर स्तर पर परमाणु हैं, और हार्डवेयर अनुकूलित/झूठ बोल सकते हैं हालांकि यह उचित लगता है।

अब क्यों पढ़ना पर्याप्त है: प्रत्येक आर्किटेक्चर के लिए मेमोरी मॉडल अलग हैं। कई आर्किटेक्चर एक निश्चित बाइट ऑफसेट, या लंबाई में एक्स शब्द आदि के साथ गठबंधन डेटा के लिए परमाणु पढ़ने या लिखने की गारंटी दे सकते हैं और सीपीयू से सीपीयू में भिन्न हो सकते हैं। लिनक्स कर्नेल में विभिन्न आर्किटेक्चर के लिए कई परिभाषाएं हैं जो बिना किसी परमाणु कॉल (CMPXCHG) मूल रूप से प्लेटफार्मों पर गारंटी देती हैं जो गारंटी देते हैं (कभी-कभी केवल अभ्यास में भी, भले ही वास्तविकता में उनके spec का कहना है कि वास्तव में गारंटी नहीं है) परमाणु पढ़ता है/लिखते हैं।

volatile का सवाल है, जबकि वहाँ सामान्य में यह के लिए कोई जरूरत नहीं है जब तक आप तक पहुँच रहे हैं स्मृति-मैप किया आईओ, यह सब जब/जहां/क्यों atomic_read और atomic_write मैक्रो कहा जा रहा है पर निर्भर करता है। कई कंपाइलर (हालांकि यह सी स्पेक में सेट नहीं है) अस्थिर चर के लिए मेमोरी बाधाएं/बाड़ उत्पन्न करता है (मेरे सिर के ऊपर से जीसीसी, एक है। एमएसवीसी निश्चित रूप से करता है।)। हालांकि यह सामान्यतः का अर्थ है कि सभी इस चर को पढ़ता/लिखता है अब आधिकारिक रूप से किसी भी संकलक अनुकूलन से मुक्त है, इस मामले में "आभासी" अस्थिर चर बनाकर केवल पढ़ने/लिखने का यह विशेष उदाहरण बंद है अनुकूलन और पुन: आदेश के लिए -limits।

2

यदि आप किसी विशिष्ट आर्किटेक्चर के लिए लिखते हैं, तो आप इसके लिए विशिष्ट धारणाएं बना सकते हैं।
मुझे लगता है कि आईए -64 इन चीजों को एक ही निर्देश में संकलित करता है।

कैश एक मुद्दा नहीं होना चाहिए, जब तक काउंटर कैश लाइन सीमा को पार न करे। लेकिन अगर 4/8 बाइट संरेखण की आवश्यकता है, तो ऐसा नहीं हो सकता है।

एक मशीन निर्देश दो मेमोरी एक्सेस में अनुवाद करते समय एक "वास्तविक" परमाणु निर्देश की आवश्यकता होती है। यह वृद्धि के लिए मामला है (पढ़ें, वृद्धि, लिखें) या & स्वैप की तुलना करें।

volatile संकलक द्वारा किए जा सकने वाले अनुकूलन को प्रभावित करता है।
उदाहरण के लिए, यह संकलक को कई पढ़ने को एक पठन में परिवर्तित करने से रोकता है।
लेकिन मशीन निर्देश स्तर पर, यह कुछ भी नहीं करता है।

3

पढ़ना अधिकांश प्रमुख आर्किटेक्चर पर परमाणु हैं, जब तक कि वे अपने आकार के एक से अधिक (और एक प्रकार के पढ़ने के आकार से बड़े नहीं होते हैं), इंटेल आर्किटेक्चर मैनुअल देखें। दूसरी तरफ लिखते हैं कि कई अलग-अलग होते हैं, इंटेल कहते हैं कि x86 के तहत, एकल बाइट लिखना और गठबंधन लिखना परमाणु हो सकता है, आईपीएफ (आईए 64) के तहत, सबकुछ अधिग्रहण और सेमेन्टिक्स जारी करता है, जो इसे परमाणु की गारंटी देगा, this देखें।

volatile संकलक को स्थानीय रूप से मूल्य कैशिंग करने से रोकता है, जिससे इसे पुनर्प्राप्त करने के लिए मजबूर किया जाता है जहां कभी भी इसका उपयोग होता है।

+0

आधुनिक कर्नेल में, 'अस्थिर' का उपयोग 'READ_ONCE() '/' WRITE_ONCE' नामक मैक्रो के माध्यम से किया जाता है। मेरे सिर में व्याख्या यह है कि संकलक तकनीकी रूप से मूल्य * एकाधिक * बार पढ़ने/लिखने की अनुमति देते हैं। जैसे यदि कोड स्थानीय चर के लिए एक पढ़ा गया मान प्रतिलिपि बनाता है, जिसका उपयोग विभिन्न स्थानों पर किया जाता है। इसलिए हमें इसे स्थानीय रूप से कैश करने के लिए मूल्य को रोकने से थोड़ा अधिक वर्णन करना होगा। पूरा विवरण: https://lwn.net/Articles/508991/ – sourcejedi

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