क्या सी ++ संकलक इस ऑपरेशन को अनुकूलित करता है?क्या आधुनिक कंपाइलर x * 2 ऑपरेशन को x << 1 में अनुकूलित करते हैं?
मुझे विश्वास है कि हाँ।
क्या सी ++ संकलक इस ऑपरेशन को अनुकूलित करता है?क्या आधुनिक कंपाइलर x * 2 ऑपरेशन को x << 1 में अनुकूलित करते हैं?
मुझे विश्वास है कि हाँ।
की शक्तियों द्वारा moduli का अनुकूलन वास्तव में VS2008 को यह अनुकूलन कर x + x:
01391000 push ecx
int x = 0;
scanf("%d", &x);
01391001 lea eax,[esp]
01391004 push eax
01391005 push offset string "%d" (13920F4h)
0139100A mov dword ptr [esp+8],0
01391012 call dword ptr [__imp__scanf (13920A4h)]
int y = x * 2;
01391018 mov ecx,dword ptr [esp+8]
0139101C lea edx,[ecx+ecx]
एक 64 में इसे बनाने और भी अधिक स्पष्ट है और उपयोग करता है:
int y = x * 2;
000000013FB9101E mov edx,dword ptr [x]
printf("%d", y);
000000013FB91022 lea rcx,[string "%d" (13FB921B0h)]
000000013FB91029 add edx,edx
यह 'अधिकतम गति' (/ ओ 2)
यदि एक्स एक फ्लोट नहीं है तो यह नहीं होगा।
हां, वे करेंगे।
हां। वे अन्य समान संचालन को भी अनुकूलित करते हैं, जैसे दो की गैर-शक्तियों द्वारा गुणा करके जिसे कुछ बदलावों की रकम के रूप में फिर से लिखा जा सकता है। वे 2 की शक्तियों द्वारा दाएं-बदलावों में विभाजन को अनुकूलित भी करेंगे, लेकिन सावधान रहें कि हस्ताक्षरित पूर्णांक के साथ काम करते समय, दो ऑपरेशन अलग-अलग होते हैं! संकलक को कुछ अतिरिक्त बिट ट्विडलिंग निर्देशों को उत्सर्जित करना है ताकि यह सुनिश्चित किया जा सके कि परिणाम सकारात्मक और नकारात्मक संख्याओं के लिए समान हैं, लेकिन यह विभाजन करने से अभी भी तेज़ है। यह भी इसी तरह 2.
कंपाइलर को वास्तव में विभाजन के लिए कोई अतिरिक्त निर्देश नहीं छोड़ना पड़ता है - यही वह है जो एसएएल है - यह दो पूरक संख्याओं को सही तरीके से संभालता है। – Branan
एर हाँ (जहां एसएएल द्वारा आप एसएआर मतलब था); यह 2 की शक्तियों द्वारा हस्ताक्षरित मॉड्यूलि के लिए है जिसमें यह अतिरिक्त बिट ट्विडलिंग कोड –
वीएस 2008 ने ऑप्टिमाइज़ेशन सेटिंग्स को x < < पर अनुकूलित किया है 1.
x = x * 2;
004013E7 mov eax,dword ptr [x]
004013EA shl eax,1
004013EC mov dword ptr [x],eax
संपादित करें: यह ऑप्टिमाइज़ेशन अक्षम (/ ओडी) के साथ वीएस डिफ़ॉल्ट "डीबग" कॉन्फ़िगरेशन का उपयोग कर रहा था। किसी ऑप्टिमाइज़ेशन स्विच (/ ओ 1,/ओ 2 (वीएस "रिटेल"), या/ऑक्स का उपयोग करके) ऐड सेल्फ कोड रॉब पोस्ट किया गया है। इसके अलावा, केवल अच्छे उपाय के लिए, मैंने सत्यापित किया है कि x = x << 1
वास्तव में दोनों/ओडी और/ऑक्स में सीएल कंपाइलर द्वारा x = x * 2
जैसा व्यवहार किया जाता है। तो, संक्षेप में, x86 के लिए cl.exe संस्करण 15.00.30729.01 * 2
और << 1
समान रूप से व्यवहार करता है और मुझे उम्मीद है कि लगभग सभी अन्य हालिया कंपाइलर भी ऐसा ही करेंगे।
आपको यह सूचीबद्ध करना चाहिए कि आप किस संकलन सेटिंग्स का उपयोग कर रहे थे –
यह आपके पास क्या संकलक है इस पर निर्भर करता है। उदाहरण के लिए दृश्य सी ++ अनुकूलन में कुख्यात रूप से खराब है। यदि आप अपनी पोस्ट को यह कहने के लिए संपादित करते हैं कि आप किस कंपाइलर का उपयोग कर रहे हैं, तो इसका उत्तर देना आसान होगा।
? सबसे पहले मैं इसके बारे में सुन रहा हूँ। असल में, मैं आमतौर पर सुनता हूं कि यह ऑप्टिमाइज़ेशन के लिए सर्वश्रेष्ठ पीसी स्तर के कंपाइलरों में से एक है। –
कोई सबूत है कि वीसी ++ "अनुकूलन में कुख्यात रूप से खराब" है? उदाहरण के लिए, हमें विभिन्न कंप्यूटर्स द्वारा उसी स्रोत से उत्पन्न मशीन कोड दिखाएं। –
@ जेम्स: http://www.ddj.com/184405641 <- बड़ा लेख। http://www.ddj.com/showArticle.jhtml?documentID=ddj0405a&pgno=12 <- निष्कर्ष निकालने वाली तालिका मैं यह नहीं कह रहा हूं कि यह एक लेख मानक है, लेकिन मैं लिनक्स समुदाय में हूं, मैं वीसी ++ के बारे में बुरी टिप्पणियां नहीं सुनता अक्सर, लेकिन पर्याप्त है। –
उत्तर "यदि यह तेज़ है" (या छोटा) है। यह लक्षित आर्किटेक्चर पर निर्भर करता है साथ ही किसी दिए गए कंपाइलर के लिए रजिस्टर उपयोग मॉडल पर निर्भर करता है। आम तौर पर, जवाब "हां, हमेशा" होता है क्योंकि यह लागू करने के लिए एक बहुत ही सरल पेफोल अनुकूलन है और आमतौर पर एक सभ्य जीत है।
जब तक किसी भाषा मानक में कुछ निर्दिष्ट नहीं किया जाता है, तो आपको इस तरह के प्रश्न का कोई गारंटी नहीं मिलेगा। जब संदेह होता है कि आपके कंपाइलर थूकते हैं तो कोड इकट्ठा करें और जांचें। वास्तव में यह जानने का एकमात्र तरीका होगा।
रेमंड चेन से यह लेख दिलचस्प हो सकता है:
जब एक्स/2 एक्स >> 1 से अलग है?: http://blogs.msdn.com/oldnewthing/archive/2005/05/27/422551.aspx
रेमंड का हवाला देते हुए:
बेशक, संकलक इस समझते हैं और अपने गुणन को फिर से लिखने या ऑपरेशन शिफ्ट करने के लिए स्वतंत्र है।वास्तव में, ऐसा करने की बहुत संभावना है, क्योंकि x + x गुणा या शिफ्ट की तुलना में अधिक आसानी से जोड़ा जा सकता है। आपकी शिफ्ट या गुणा-दर-दो शायद एक ऐड ईएक्स, ईएक्स निर्देश के करीब कुछ के रूप में फिर से लिखा जा रहा है।
[...]
यहां तक कि अगर आप को लगता है कि बदलाव संकेत बिट से भर जाता है, बदलाव और भाग का परिणाम अलग अगर एक्स नकारात्मक है कर रहे हैं।
(-1)/2 ≡ 0
(-1) >> 1 ≡ -1[...]
कहानी का नैतिक लिखने के लिए तुम क्या मतलब है । यदि आप दो से विभाजित करना चाहते हैं, तो "/ 2" लिखें, न कि ">> 1"। संकलक बेहतर अनुकूलन के छोटे पैमाने पर कोड (के लिए धन्यवाद में एक मानव की तुलना में है:
हम केवल यह मान सकते हैं संकलक आप क्या चाहते हैं, क्या नहीं तुम उसे क्या करना चाहते हैं यह बताने के लिए बुद्धिमान है डेमिन इस सूक्ष्म बिंदु को इंगित करने के लिए): यदि आप वास्तव में अनुकूलन चाहते हैं, तो एक प्रोफाइलर का उपयोग करें, और अपने एल्गोरिदम की दक्षता का अध्ययन करें।
प्रश्न पूछने वाले छोटे पैमाने पर कोड को कम से कम अनुकूलित करने के लिए, मानव को अभी भी algotirhm लिखना चाहिए :-) – Daemin
@ डेमिन: आप काफी सही हैं – paercebal
सी ++ में शिफ्ट ऑपरेटर का कार्यान्वयन वास्तव में प्लेटफार्म विशिष्ट है; कुछ प्लेटफार्मों में अंकगणित बदलाव होता है। हालांकि x86 राउंड पर गलत है। इसका मतलब यह है कि संकलक उस मामले में एसएआर का सुरक्षित रूप से उपयोग नहीं कर सकता है जबकि एक मानव (परिणामों को जानना) कर सकता है। –
मुझे यकीन है कि वे सभी इस तरह के अनुकूलन करते हैं, लेकिन मुझे आश्चर्य है कि वे अभी भी प्रासंगिक हैं या नहीं। पुराने प्रोसेसर ने स्थानांतरण और जोड़कर गुणा किया, जो कई चक्रों को पूरा करने में लग सकता था। दूसरी तरफ, आधुनिक प्रोसेसर में बैरल-शिफ्टर्स का एक सेट होता है जो एक घड़ी चक्र या उससे कम में सभी आवश्यक बदलाव और जोड़ों को एक साथ कर सकता है। क्या किसी ने वास्तव में बेंचमार्क किया है कि क्या इन अनुकूलन वास्तव में मदद करते हैं?
@ फेरूरुसीओ बरलेट
यह एक अच्छा सवाल है। मैं जवाब खोजने की कोशिश करने के लिए गुगलिंग गया।
मुझे इंटेल प्रोसेसर के लिए सीधे जवाब नहीं मिल सका, लेकिन this पृष्ठ में कोई ऐसा व्यक्ति है जिसने समय की कोशिश की। यह बदलावों को विज्ञापन और गुणा के रूप में तेज़ी से दोगुना से अधिक होने लगता है। बिट बदलाव इतनी सरल हैं (जहां एक गुणा एक शिफ्ट और एक जोड़ा हो सकता है) कि यह समझ में आता है।
तो फिर मैंने एएमडी गुगल किया, और 2002 से एथलॉन के लिए पुरानी अनुकूलन मार्गदर्शिका पाई, जिसमें सूचियां 2 से 32 के बीच contants द्वारा संख्याओं को गुणा करने के सबसे तेज़ तरीके सूचीबद्ध करती हैं। दिलचस्प बात यह है कि यह संख्या पर निर्भर करता है। कुछ विज्ञापन हैं, कुछ बदलाव। यह page 122 पर है।
Athlon 64 के लिए एक गाइड एक ही चीज़ दिखाता है (पृष्ठ 164 या तो)। यह कहता है कि गुणा 3 (32-बिट में) या 4 (64-बिट में) चक्र संचालन होते हैं, जहां बदलाव 1 होते हैं और जोड़ते हैं 2.
ऐसा लगता है कि यह अभी भी अनुकूलन के रूप में उपयोगी है।
चक्र गणना को अनदेखा करते हुए, इस तरह की विधि आपको गुणा निष्पादन इकाइयों (संभवतः) को बांधने से रोकती है, इसलिए यदि आप एक तंग लूप में बहुत से गुणा कर रहे थे, जहां कुछ स्थिरांक का उपयोग करते हैं और कुछ अतिरिक्त नहीं होते हैं शेड्यूलिंग रूम उपयोगी हो सकता है।
लेकिन यह अनुमान है।
यह केवल ऑप्टिमाइज़र क्या कर सकता है इसकी शुरुआत है। यह देखने के लिए कि आपका कंपाइलर क्या करता है, स्विच के लिए देखो जो इसे असेंबलर स्रोत को उत्सर्जित करने का कारण बनता है। डिजिटल मंगल कंपाइलरों के लिए, आउटपुट असेंबलर की जांच ओबीजे 2 एएसएम उपकरण के साथ की जा सकती है।यदि आप सीखना चाहते हैं कि आपका कंपाइलर कैसे काम करता है, तो असेंबलर आउटपुट को देखते हुए बहुत रोशनी हो सकती है।
जीसीसी एक ही चीज करता है (मैंने पहले से ही लीआ का उपयोग करने के कई बार देखा है, और आपके नमूना प्रोग्राम को संकलित करते हुए इसे -m32 और -m64 दोनों के साथ जोड़ दिया गया है)। – CesarB
इस जानकारी को देखने का एक त्वरित तरीका: ब्याज की रेखा पर ब्रेकपॉइंट डालें, डीबग मोड में चलाएं। जब यह लाइन पर रुक जाता है, तो राइट क्लिक करें और "डिस्सेप्लेस पर जाएं" चुनें। यहां अन्य विधियां: https://stackoverflow.com/questions/1020498/how-to-view-the-assembly-behind-the-code-using-visual-c – RoG