2011-12-08 14 views
14

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

मैं समझ सकता हूं कि क्यों इंटेल मूल रूप से प्रतिनिधि निर्देशों को लागू करता था जब प्रोसेसर केवल एक समय में एक निर्देश चलाते थे, लेकिन क्या अब उनका उपयोग करने का कोई फायदा है?

एक लूप के साथ जो अधिक निर्देशों को संकलित करता है, वहां पाइपलाइन को भरने और/या ऑर्डर जारी करने के लिए और कुछ भी है। क्या आधुनिक प्रोसेसर इन rep-prefixed निर्देशों के लिए अनुकूलित करने के लिए बनाया गया है, या आधुनिक कोड में शायद ही कभी निर्देशों का उपयोग किया जाता है कि वे निर्माताओं के लिए महत्वपूर्ण नहीं हैं?

+0

मैंने इसमें 5 साल की तरह नहीं देखा है, लेकिन फिर मेरे व्यक्तिगत अनुभव यह था कि कम से कम प्रतिनिधि movsd और rep stosd एक साधारण पाश से तेज थे जबकि स्कैनिंग संस्करणों में से कुछ नहीं थे। हालांकि, यह काफी महत्वपूर्ण हो सकता है। –

+0

विभिन्न प्रोसेसर पर एक परीक्षण आयोजित करें और खुद के लिए देखें। –

+0

इनपुट, दोस्तों के लिए धन्यवाद। एलेक्स: मैं शायद अंततः, लेकिन मेरे पास कोशिश करने के लिए कई अलग-अलग प्रोसेस नहीं हैं, इसलिए यह एक असली प्रो बनाम एक एमुलेटर पर होगा जिसमें पाइपलाइन नहीं होगी। इसके अलावा, मैं आलसी हूं और अगर वह किसी और ने इसे पहले ही कर लिया हो तो वह काम नहीं करेगा। :) – RyanS

उत्तर

33

एएमडी और इंटेल के अनुकूलन मार्गदर्शिका दोनों में इस तरह के प्रश्नों के लिए बहुत सी जगह दी गई है।

  • AMD Software Optimization Guide (Sep/2005), खंड 8.3, स्नातकोत्तर: अलग सीपीयू पीढ़ियों, अलग ढंग से व्यवहार उदाहरण के लिए - इस क्षेत्र में दी गयी सलाह की वैधता "आधा जीवन" है। 167:
    स्ट्रिंग ऑपरेशंस करते समय आरईपी उपसर्ग का उपयोग करने से बचें, खासकर जब स्मृति के ब्लॉक की प्रतिलिपि बनाते हैं।
  • AMD Software Optimization Guide (Apr/2011), धारा 9.3, पृष्ठ। 148:
    स्ट्रिंग ऑपरेशंस करते समय आरईपी उपसर्ग को का उपयोग करें।

Intel Architecture Optimization Manual पर तालिका 7-2 (rep stosd सहित) विभिन्न ब्लॉक प्रति तकनीकों के लिए प्रदर्शन की तुलना आंकड़े देता है। मेमोरी कॉपी रूटीन के संबंधित प्रदर्शन, पृष्ठ। 7-37f।, विभिन्न CPUs के लिए, और फिर एक पर सबसे तेज़ क्या हो सकता है दूसरों पर सबसे तेज़ नहीं हो सकता है।

कई मामलों के लिए, हालिया x86 CPUs (जिसमें "स्ट्रिंग" एसएसई 4.2 ऑपरेशंस है) सिम इकाई के माध्यम से स्ट्रिंग ऑपरेशन कर सकते हैं, this investigation देखें।

इस सब पर अनुवर्ती करने के लिए (और/या चीजें फिर से बदलते समय खुद को अद्यतन रखें), Agner Fog's Optimization guides/blogs पढ़ें।

+0

+1 उत्कृष्ट जवाब। एग्नेर फोग की साइट पर भी अच्छी जानकारी का नाव भार है। –

+4

+1 एग्नेर फॉग – hirschhornsalz

+0

'रेप मूव्स' और 'रेप स्टोस' का उल्लेख करने के लिए +1 आमतौर पर अच्छा होता है (मध्यम से बड़े गठबंधन बफर के लिए), 'दोहराना/रेपेन स्कैस/सेमीपीएस' आमतौर पर अच्छा नहीं होता है। –

8

फ्रैंकएच के उत्कृष्ट उत्तर के अतिरिक्त; मैं यह इंगित करना चाहता हूं कि कौन सी विधि सर्वोत्तम है स्ट्रिंग की लंबाई, इसके संरेखण, और यदि लंबाई तय या परिवर्तनीय है, तो यह भी निर्भर करती है।

छोटे तारों (शायद लगभग 16 बाइट्स) के लिए इसे सरल निर्देशों के साथ मैन्युअल रूप से करने के लिए संभवतः तेज़ है, क्योंकि यह अधिक जटिल तकनीकों की सेटअप लागत से बचाता है (और निश्चित आकार तारों के लिए आसानी से अनलॉक किया जा सकता है)। मध्यम आकार के तारों के लिए (शायद 16 बाइट्स से 4 कीबीबी तक) "आरईपी MOVSD" जैसे कुछ (कुछ गलत तरीके से गलत होने पर "MOVSB" निर्देशों को फेंक दिया गया है) सबसे अच्छा होने की संभावना है।

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

यह भी ध्यान दें कि (इन लम्बाई, संरेखण, निश्चित या परिवर्तनीय आकार, सीपीयू प्रकार इत्यादि) के कारण इन बहु मतभेदों (संभावित लंबाई, संरेखण, निश्चित या परिवर्तनीय आकार, सीपीयू प्रकार, आदि) के कारण (सुविधा के बजाय अनुकूलन के उद्देश्य के लिए) एक बहु-उद्देश्य "memcpy () "सभी अलग-अलग मामलों के लिए नज़दीक है।

+2

एएके। ऑप्टिमाइज़ेशन मार्गदर्शिकाएं (इंटेल/एएमडी दोनों के साथ-साथ एग्नेर फोग की सामग्री और कई अन्य) इन चीजों का भी उल्लेख करते हैं; कई मामलों में, एक रणनीति: 1. लघु तारों के लिए, रेखांकित प्राचीन निर्देश 2।मध्यम आकार के लिए, बड़े ऑपरेंड-आकार 'रेप मूव्स' 3. ज्ञात बड़े ब्लॉक के लिए, सिम इकाइयों का उपयोग करें। और हमेशा _your_ डेटा पर परीक्षण करें, क्योंकि 'अल्ट्रा-फास्ट वीवीएक्स' प्रदर्शन टूट जाएगा यदि आपके अधिकांश स्ट्रिंग <8 बाइट्स हैं। –

+0

आईआईआरसी 'आरईपी एमओवीएसडी 'आधुनिक हार्डवेयर पर अक्सर' आरईपी MOVSB ​​'की तुलना में बहुत धीमी * है। संभवतः क्योंकि आधुनिक सीपीयू में केवल 'आरईपी एमओवीएसबी' के लिए विशेष अनुकूलन होते हैं, क्योंकि इसका उपयोग 'आरईपी MOVSD' से कहीं अधिक बार किया जाता है। –

+0

@PaulGroke: शायद कुछ सीपीयू हैं जहां 'rep movsb'' rep movsd' से बेहतर है, लेकिन अधिकांश 'rep movsd' /' movsq' के लिए सभी ERMSB जादू को भी लागू करते हैं। और 'रेव movsb' आमतौर पर IvyBridge की उन्नत प्रतिनिधि MovSB सुविधा से पहले इंटेल CPUs पर * बदतर * था। देखें [memcpy के लिए उन्नत आरईपी MOVSB] (https://stackoverflow.com/questions/43343231/enhanced-rep-movsb-for-memcpy), जिसमें x86 मेमोरी बैंडविड्थ के बारे में बहुत सारी जानकारी के साथ * उत्कृष्ट * उत्तर है। –

0

चूंकि किसी ने आपको कोई संख्या नहीं दी है, इसलिए मैं आपको कुछ कचरा कलेक्टर बेंचमार्क करके पाया है जो बहुत ही गड़बड़ है। प्रतिलिपि बनाने के लिए मेरी वस्तुओं 60% 16 बाइट लंबाई में हैं और शेष 30% 500 - 8000 बाइट्स हैं या तो।

  • पूर्वशर्त: दोनों dst, src और n 8.
  • प्रोसेसर के गुणकों हैं: AMD Phenom (टीएम) द्वितीय X6 1090T प्रोसेसर 64 बिट/लिनक्स

यहाँ मेरी तीन memcpy वेरिएंट हैं:

हाथ कोडित जबकि पाश:

if (n == 16) { 
    *dst++ = *src++; 
    *dst++ = *src++; 
} else { 
    size_t n_ptrs = n/sizeof(ptr); 
    ptr *end = dst + n_ptrs; 
    while (dst < end) { 
     *dst++ = *src++; 
    } 
} 

(ptruintptr_t पर उपनाम है)। समय: 101.16%

rep movsb

if (n == 16) { 
    *dst++ = *src++; 
    *dst++ = *src++; 
} else { 
    asm volatile("cld\n\t" 
       "rep ; movsb" 
       : "=D" (dst), "=S" (src) 
       : "c" (n), "D" (dst), "S" (src) 
       : "memory"); 
} 

समय: 103.22%

rep movsq

if (n == 16) { 
    *dst++ = *src++; 
    *dst++ = *src++; 
} else { 
    size_t n_ptrs = n/sizeof(ptr); 
    asm volatile("cld\n\t" 
       "rep ; movsq" 
       : "=D" (dst), "=S" (src) 
       : "c" (n_ptrs), "D" (dst), "S" (src) 
       : "memory"); 
} 

समय: 100.00%

req movsq एक छोटे अंतर से जीत।

+1

आरसीएक्स रजिस्टर आरईपी एमओवीएस द्वारा भी बदला जाता है। –

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