ताकत में कमी
कंपाइलर निर्माण में, ताकत में कमी एक कंपाइलर अनुकूलन है जहां महंगे ऑपरेशन को समकक्ष लेकिन कम महंगे ऑपरेशन से बदल दिया जाता है।[1] ताकत में कमी का क्लासिक उदाहरण एक लूप के अंदर मजबूत गुणन को कमजोर परिवर्धन में परिवर्तित करता है - कुछ ऐसा जो अक्सर सरणी एड्रेसिंग में होता है।(Cooper, Simpson & Vick 1995, p. 1)
ताकत में कमी के उदाहरणों में एक लूप के भीतर गुणन को एक जोड़ के साथ बदलना और एक लूप के भीतर घातांक को गुणन के साथ बदलना शामिल है।
कोड विश्लेषण
किसी प्रोग्राम के निष्पादन का अधिकांश समय आमतौर पर कोड के एक छोटे से भाग (जिसे हॉट स्पॉट (कंप्यूटर प्रोग्रामिंग) कहा जाता है) में व्यतीत होता है, और वह कोड अक्सर एक लूप के अंदर होता है जिसे बार-बार निष्पादित किया जाता है।
एक कंपाइलर लूप की पहचान करने और उन लूप के भीतर रजिस्टर मानों की विशेषताओं को पहचानने के लिए तरीकों का उपयोग करता है। शक्ति में कमी के लिए, संकलक की रुचि इसमें है:
- लूप इनवेरिएंट: वे मान जो लूप के शरीर के भीतर नहीं बदलते हैं।
- प्रेरण चर: वे मान जो लूप के माध्यम से हर बार पुनरावृत्त किए जा रहे हैं।
लूप इनवेरिएंट अनिवार्य रूप से एक लूप के भीतर स्थिरांक होते हैं, लेकिन उनका मान लूप के बाहर बदल सकता है। प्रेरण चर ज्ञात मात्रा के अनुसार बदल रहे हैं। शर्तें एक विशेष लूप से संबंधित हैं। जब लूप नेस्टेड होते हैं, तो बाहरी लूप में एक इंडक्शन वेरिएबल आंतरिक लूप में एक लूप इनवेरिएंट हो सकता है।
शक्ति में कमी एक लूप इनवेरिएंट और एक इंडक्शन वेरिएबल से जुड़े भावों की तलाश करती है। उनमें से कुछ अभिव्यक्तियों को सरल बनाया जा सकता है। उदाहरण के लिए, लूप इनवेरिएंट का गुणन c
और प्रेरण चर i
c = 7;
for (i = 0; i < N; i++)
{
y[i] = c * i;
}
क्रमिक कमजोर परिवर्धन द्वारा प्रतिस्थापित किया जा सकता है
c = 7;
k = 0;
for (i = 0; i < N; i++)
{
y[i] = k;
k = k + c;
}
ताकत में कमी का उदाहरण
नीचे एक उदाहरण दिया गया है जो सरणी अनुक्रमण पता गणना से उत्पन्न होने वाले सभी लूप गुणन को मजबूत करेगा।
एक साधारण लूप की कल्पना करें जो पहचान मैट्रिक्स में एक सरणी सेट करता है।
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
A[i,j] = 0.0;
}
A[i,i] = 1.0;
}
मध्यवर्ती कोड
कंपाइलर इस कोड को इस रूप में देखेगा
0010 ; for (i = 0, i < n; i++)
0020 ; {
0030 r1 = #0 ; i = 0
0040 G0000:
0050 load r2, n ; i < n
0060 cmp r1, r2
0070 bge G0001
0080
0090 ; for (j = 0; j < n; j++)
0100 ; {
0110 r3 = #0 ; j = 0
0120 G0002:
0130 load r4, n ; j < n
0140 cmp r3, r4
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0180 load r7, n
0190 r8 = r1 * r7 ; calculate subscript i * n + j
0200 r9 = r8 + r3
0210 r10 = r9 * #8 ; calculate byte address
0220 fr3 = #0.0
0230 fstore fr3, A[r10]
0240
0250 r3 = r3 + #1 ; j++
0260 br G0002
0270 ; }
0280 G0003:
0290 ; A[i,i] = 1.0;
0300 load r12, n ; calculate subscript i * n + i
0310 r13 = r1 * r12
0320 r14 = r13 + r1
0330 r15 = r14 * #8 ; calculate byte address
0340 fr4 = #1.0
0350 fstore fr4, A[r15]
0360
0370 ; i++
0380 r1 = r1 + #1
0390 br G0000
0400 ; }
0410 G0001:
यह 2-आयामी सरणी A को n*n आकार के 1-आयामी सरणी के रूप में व्यक्त करता है, ताकि जब भी उच्च-स्तरीय कोड A[x, y] को व्यक्त करे तो यह आंतरिक रूप से किसी के लिए A[(x*n)+y] होगा। वैध सूचकांक x और y दिए गए हैं।
कई अनुकूलन
कंपाइलर कई अनुकूलन करना शुरू कर देगा - न कि केवल ताकत में कमी। अभिव्यक्तियाँ जो एक लूप के भीतर स्थिर (अपरिवर्तनीय) हैं, लूप के बाहर लूप-अपरिवर्तनीय कोड गति होंगी। स्थिरांक को दोनों लूपों के बाहर लोड किया जा सकता है - जैसे फ़्लोटिंग पॉइंट रजिस्टर fr3 और fr4। यह मान्यता कि कुछ चर नहीं बदलते हैं, रजिस्टरों को मर्ज करने की अनुमति देता है; n स्थिर है, इसलिए r2, r4, r7, r12 को फहराया और ढहाया जा सकता है। सामान्य मान i*n की गणना (उठाए गए) r8 और r13 में की जाती है, इसलिए वे ढह जाते हैं। सबसे भीतरी लूप (0120-0260) को 11 से घटाकर 7 मध्यवर्ती निर्देश कर दिया गया है। अंतरतम लूप में जो एकमात्र गुणन बचता है वह है पंक्ति 0210 का 8 से गुणा करना।
0010 ; for (i = 0, i < n; i++)
0020 {
0030 r1 = #0 ; i = 0
0050 load r2, n
0130 ; load r4, n killed; use r2
0180 ; load r7, n killed; use r2
0300 ; load r12, n killed; use r2
0220 fr3 = #0.0
0340 fr4 = #1.0
0040 G0000:
0060 cmp r1, r2 ; i < n
0070 bge G0001
0080
0190 r8 = r1 * r2 ; calculate subscript i * n
0310 ; r13 = r1 * r2 killed; use r8 ; calculate subscript i * n
0090 ; for (j = 0; j < n; j++)
0100 {
0110 r3 = #0 ; j = 0
0120 G0002:
0140 cmp r3, r2 ; j < n
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0200 r9 = r8 + r3 ; calculate subscript i * n + j
0210 r10 = r9 * #8 ; calculate byte address
0230 fstore fr3, A[r10]
0240
0250 r3 = r3 + #1 ; j++
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0320 r14 = r8 + r1 ; calculate subscript i * n + i
0330 r15 = r14 * #8 ; calculate byte address
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 r1 = r1 + #1
0390 br G0000
0400 }
0410 G0001:
करने के लिए और भी अनुकूलन हैं. रजिस्टर r3 अंतरतम लूप (0140-0260) में मुख्य चर है; यह लूप के माध्यम से हर बार 1 से बढ़ जाता है। रजिस्टर r8 (जो अंतरतम लूप में अपरिवर्तनीय है) को r3 में जोड़ा जाता है। r3 का उपयोग करने के बजाय, कंपाइलर r3 को हटा सकता है और r9 का उपयोग कर सकता है। लूप को r3 = 0 से n-1 द्वारा नियंत्रित करने के बजाय, r9=r8+0 से r8+n-1 द्वारा नियंत्रित किया जा सकता है। वह चार निर्देश जोड़ता है और चार निर्देश समाप्त कर देता है, लेकिन लूप के अंदर एक निर्देश कम हो जाता है।
0110 ; r3 = #0 killed ; j = 0
0115 r9 = r8 ; new assignment
0117 r20 = r8 + r2 ; new limit
0120 G0002:
0140 ; cmp r3, r2 killed ; j < n
0145 cmp r9, r20 ; r8 + j < r8 + n = r20
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0200 ; r9 = r8 + r3 killed ; calculate subscript i * n + j
0210 r10 = r9 * #8 ; calculate byte address
0230 fstore fr3, A[r10]
0240
0250 ; r3 = r3 + #1 killed ; j++
0255 r9 = r9 + #1 ; new loop variable
0260 br G0002
अब r9 लूप वैरिएबल है, लेकिन यह 8 से गुणा के साथ इंटरैक्ट करता है। यहां हमें ताकत में कुछ कमी करने को मिलती है। 8 से गुणा करने पर 8 के कुछ क्रमिक जोड़ कम हो सकते हैं। अब लूप के अंदर कोई गुणा नहीं है।
0115 r9 = r8 ; new assignment
0117 r20 = r8 + r2 ; new limit
0118 r10 = r8 * #8 ; initial value of r10
0120 G0002:
0145 cmp r9, r20 ; r8 + j < r8 + n = r20
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0210 ; r10 = r9 * #8 killed ; calculate byte address
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0255 r9 = r9 + #1 ; loop variable
0260 br G0002
रजिस्टर r9 और r10 (= 8*r9) दोनों की आवश्यकता नहीं है; r9 को लूप में समाप्त किया जा सकता है। लूप अब 5 निर्देश है।
0115 ; r9 = r8 killed
0117 r20 = r8 + r2 ; limit
0118 r10 = r8 * #8 ; initial value of r10
0119 r22 = r20 * #8 ; new limit
0120 G0002:
0145 ; cmp r9, r20 killed ; r8 + j < r8 + n = r20
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0255 ; r9 = r9 + #1 killed ; loop variable
0260 br G0002
बाहरी लूप
पूरी तस्वीर पर वापस जाएँ:
0010 ; for (i = 0, i < n; i++)
0020 {
0030 r1 = #0 ; i = 0
0050 load r2, n
0220 fr3 = #0.0
0340 fr4 = #1.0
0040 G0000:
0060 cmp r1, r2 ; i < n
0070 bge G0001
0080
0190 r8 = r1 * r2 ; calculate subscript i * n
0117 r20 = r8 + r2 ; limit
0118 r10 = r8 * #8 ; initial value of r10
0119 r22 = r20 * #8 ; new limit
0090 ; for (j = 0; j < n; j++)
0100 {
0120 G0002:
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0320 r14 = r8 + r1 ; calculate subscript i * n + i
0330 r15 = r14 * #8 ; calculate byte address
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 r1 = r1 + #1
0390 br G0000
0400 }
0410 G0001:
बाहरी लूप के भीतर अब चार गुणन हैं जो r1 बढ़ाते हैं। 0190 पर r8 = r1*r2 रजिस्टर करें, इसे लूप (0055) में प्रवेश करने से पहले सेट करके और लूप के नीचे (0385) पर r2 द्वारा बढ़ाकर इसकी ताकत को कम किया जा सकता है।
मान r8*8 (0118 पर) को इनिशियलाइज़ करके (0056) कम किया जा सकता है और r8 बढ़ने पर इसमें 8*r2 जोड़कर (0386) बढ़ाया जा सकता है।
रजिस्टर r20 को 0117 पर लूप के माध्यम से हर बार अपरिवर्तनीय/स्थिर r2 द्वारा बढ़ाया जा रहा है। बढ़ने के बाद, इसे 0119 पर r22 बनाने के लिए 8 से गुणा किया जाता है। लूप के माध्यम से हर बार 8*r2 जोड़कर उस गुणन की ताकत को कम किया जा सकता है। .
0010 ; for (i = 0, i < n; i++)
0020 {
0030 r1 = #0 ; i = 0
0050 load r2, n
0220 fr3 = #0.0
0340 fr4 = #1.0
0055 r8 = r1 * r2 ; set initial value for r8
0056 r40 = r8 * #8 ; initial value for r8 * 8
0057 r30 = r2 * #8 ; increment for r40
0058 r20 = r8 + r2 ; copied from 0117
0058 r22 = r20 * #8 ; initial value of r22
0040 G0000:
0060 cmp r1, r2 ; i < n
0070 bge G0001
0080
0190 ; r8 = r1 * r2 killed ; calculate subscript i * n
0117 ; r20 = r8 + r2 killed - dead code
0118 r10 = r40 ; strength reduced expression to r40
0119 ; r22 = r20 * #8 killed ; strength reduced
0090 ; for (j = 0; j < n; j++)
0100 {
0120 G0002:
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0320 r14 = r8 + r1 ; calculate subscript i * n + i
0330 r15 = r14 * #8 ; calculate byte address
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 r1 = r1 + #1
0385 r8 = r8 + r2 ; strength reduce r8 = r1 * r2
0386 r40 = r40 + r30 ; strength reduce expression r8 * 8
0388 r22 = r22 + r30 ; strength reduce r22 = r20 * 8
0390 br G0000
0400 }
0410 G0001:
अंतिम गुणा
इससे दो लूपों में बाहरी लूप के भीतर केवल एक गुणन ऑपरेशन (0330 पर) रह जाता है और आंतरिक लूप के भीतर कोई गुणन नहीं होता है।
0010 ; for (i = 0, i < n; i++)
0020 {
0030 r1 = #0 ; i = 0
0050 load r2, n
0220 fr3 = #0.0
0340 fr4 = #1.0
0055 r8 = r1 * r2 ; set initial value for r8
0056 r40 = r8 * #8 ; initial value for r8 * 8
0057 r30 = r2 * #8 ; increment for r40
0058 r20 = r8 + r2 ; copied from 0117
0058 r22 = r20 * #8 ; initial value of r22
0040 G0000:
0060 cmp r1, r2 ; i < n
0070 bge G0001
0080
0118 r10 = r40 ; strength reduced expression to r40
0090 ; for (j = 0; j < n; j++)
0100 {
0120 G0002:
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0320 r14 = r8 + r1 ; calculate subscript i * n + i
0330 r15 = r14 * #8 ; calculate byte address
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 r1 = r1 + #1
0385 r8 = r8 + r2 ; strength reduce r8 = r1 * r2
0386 r40 = r40 + r30 ; strength reduce expression r8 * 8
0388 r22 = r22 + r30 ; strength reduce r22 = r20 * 8
0390 br G0000
0400 }
0410 G0001:
पंक्ति 0320 पर, r14, r8 और r1 का योग है, और लूप में r8 और r1 को बढ़ाया जा रहा है। रजिस्टर r8 को r2 (=n) से टक्कर मिल रही है और r1 को 1 से टक्कर मिल रही है। नतीजतन, r14 को लूप के माध्यम से हर बार n+1 से टक्कर मिल रही है। अंतिम लूप को 0330 पर गुणा करने पर लूप के माध्यम से हर बार (r2+1)*8 जोड़कर ताकत कम की जा सकती है।
0010 ; for (i = 0, i < n; i++)
0020 {
0030 r1 = #0 ; i = 0
0050 load r2, n
0220 fr3 = #0.0
0340 fr4 = #1.0
0055 r8 = r1 * r2 ; set initial value for r8
0056 r40 = r8 * #8 ; initial value for r8 * 8
0057 r30 = r2 * #8 ; increment for r40
0058 r20 = r8 + r2 ; copied from 0117
0058 r22 = r20 * #8 ; initial value of r22
005A r14 = r8 + r1 ; copied from 0320
005B r15 = r14 * #8 ; initial value of r15 (0330)
005C r49 = r2 + #1
005D r50 = r49 * #8 ; strength reduced increment
0040 G0000:
0060 cmp r1, r2 ; i < n
0070 bge G0001
0080
0118 r10 = r40 ; strength reduced expression to r40
0090 ; for (j = 0; j < n; j++)
0100 {
0120 G0002:
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0320 ; r14 = r8 + r1 killed ; dead code
0330 ; r15 = r14 * #8 killed ; strength reduced
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 r1 = r1 + #1
0385 r8 = r8 + r2 ; strength reduce r8 = r1 * r2
0386 r40 = r40 + r30 ; strength reduce expression r8 * 8
0388 r22 = r22 + r30 ; strength reduce r22 = r20 * 8
0389 r15 = r15 + r50 ; strength reduce r15 = r14 * 8
0390 br G0000
0400 }
0410 G0001:
अभी और भी बहुत कुछ करना बाकी है. लगातार मोड़ने से प्रस्तावना में r1=0 की पहचान हो जाएगी, जिससे कई निर्देश साफ हो जाएंगे। रजिस्टर r8 का उपयोग लूप में नहीं किया जाता है, इसलिए यह गायब हो सकता है।
इसके अलावा, r1 का उपयोग केवल लूप को नियंत्रित करने के लिए किया जा रहा है, इसलिए r1 को r40 जैसे एक अलग इंडक्शन वेरिएबल द्वारा प्रतिस्थापित किया जा सकता है। जहां मैं 0 <= i < n गया, वहां रजिस्टर r40 0 <= r40 < 8 * n * n जाता है।
0010 ; for (i = 0, i < n; i++)
0020 {
0030 ; r1 = #0 ; i = 0, becomes dead code
0050 load r2, n
0220 fr3 = #0.0
0340 fr4 = #1.0
0055 ; r8 = #0 killed ; r8 no longer used
0056 r40 = #0 ; initial value for r8 * 8
0057 r30 = r2 * #8 ; increment for r40
0058 ; r20 = r2 killed ; r8 = 0, becomes dead code
0058 r22 = r2 * #8 ; r20 = r2
005A ; r14 = #0 killed ; r8 = 0, becomes dead code
005B r15 = #0 ; r14 = 0
005C r49 = r2 + #1
005D r50 = r49 * #8 ; strength reduced increment
005D r60 = r2 * r30 ; new limit for r40
0040 G0000:
0060 ; cmp r1, r2 killed ; i < n; induction variable replaced
0065 cmp r40, r60 ; i * 8 * n < 8 * n * n
0070 bge G0001
0080
0118 r10 = r40 ; strength reduced expression to r40
0090 ; for (j = 0; j < n; j++)
0100 {
0120 G0002:
0147 cmp r10, r22 ; r10 = 8*(r8 + j) < 8*(r8 + n) = r22
0150 bge G0003
0160
0170 ; A[i,j] = 0.0;
0230 fstore fr3, A[r10]
0240
0245 r10 = r10 + #8 ; strength reduced multiply
0260 br G0002
0270 }
0280 G0003:
0290 ; A[i,i] = 1.0;
0350 fstore fr4, A[r15]
0360
0370 ;i++
0380 ; r1 = r1 + #1 killed ; dead code (r40 controls loop)
0385 ; r8 = r8 + r2 killed ; dead code
0386 r40 = r40 + r30 ; strength reduce expression r8 * 8
0388 r22 = r22 + r30 ; strength reduce r22 = r20 * 8
0389 r15 = r15 + r50 ; strength reduce r15 = r14 * 8
0390 br G0000
0400 }
0410 G0001:
अन्य शक्ति कटौती ऑपरेशन
ऑपरेटर ताकत में कमी धीमे गणित संचालन को तेज संचालन के साथ बदलने के लिए पहचान (गणित) का उपयोग करती है। लाभ लक्ष्य सीपीयू और कभी-कभी आसपास के कोड पर निर्भर करते हैं (जो सीपीयू के भीतर अन्य कार्यात्मक इकाइयों की उपलब्धता को प्रभावित कर सकते हैं)।
- अंकगणितीय बदलाव या तार्किक बदलाव के साथ पूर्णांक विभाजन या गुणन को 2 की शक्ति से बदलना[2]
- बदलाव, जोड़ या घटाव के संयोजन के साथ पूर्णांक गुणन को एक स्थिरांक से बदलना
- मशीन पूर्णांकों की सीमित सीमा का लाभ उठाते हुए, पूर्णांक विभाजन को गुणन के साथ एक स्थिरांक से प्रतिस्थापित करना।[3] यह विधि तब भी काम करती है यदि भाजक एक गैर-पूर्णांक है जो 1 से काफी बड़ा है, उदाहरण के लिए √2 या π.[4]
Original calculation | Replacement calculation |
---|---|
y+= 1 | y++ |
y%2 != 0 | y & 1 |
y = x * 2 | y = x << 1 |
y = x / 2 | y = x >> 1 |
y = x % 2 | y = x & 1 |
y = x * 15 | y = (x << 4) - x |
y = (uint16_t)x / 10 | y = ((uint32_t)x * (uint32_t)0xCCCD) >> 19) |
y = (uint16_t)x / π | y = (((uint32_t)x * (uint32_t)0x45F3) >> 16) + x) >> 2) |
प्रेरण चर (अनाथ)
प्रेरण चर या पुनरावर्ती शक्ति में कमी फ़ंक्शन के पिछले मानों का उपयोग करके सरल गणना के साथ कुछ व्यवस्थित रूप से बदलते चर के फ़ंक्शन को प्रतिस्थापित करती है। एक प्रक्रियात्मक प्रोग्रामिंग भाषा में यह एक लूप वैरिएबल से जुड़े अभिव्यक्ति पर लागू होगा और एक घोषणात्मक प्रोग्रामिंग भाषा में यह एक रिकर्सन (कंप्यूटर विज्ञान) के तर्क पर लागू होगा। उदाहरण के लिए,
f x = ... (3 ** x) ... (f (x + 1)) ...
बन जाता है
f x = f' x 1
where
f' x z = ... z ... (f' (x + 1) (3 * z)) ...
यहां पुनरावर्ती फ़ंक्शन को संशोधित किया गया है f′ दूसरा पैरामीटर z = 3 ** x लेता है, जिससे महंगी गणना (3 ** x) को सस्ते (3 * z) से प्रतिस्थापित किया जा सकता है।
यह भी देखें
- तीव्र व्युत्क्रम वर्गमूल
- हैकर की प्रसन्नता
- आंशिक मूल्यांकन
टिप्पणियाँ
- ↑ Steven Muchnick; Muchnick and Associates (15 August 1997). उन्नत कंपाइलर डिज़ाइन कार्यान्वयन. Morgan Kaufmann. ISBN 978-1-55860-320-2.
ताकत में कमी.
- ↑ In languages such as C and Java, integer division has round-towards-zero semantics, whereas a bit-shift always rounds down, requiring special treatment for negative numbers. For example, in Java,
-3 / 2
evaluates to-1
, whereas-3 >> 1
evaluates to-2
. So in this case, the compiler cannot optimize division by two by replacing it by a bit shift. - ↑ Granlund, Torbjörn; Peter L. Montgomery. "गुणन का उपयोग करते हुए अपरिवर्तनीय पूर्णांकों द्वारा विभाजन" (PDF).
- ↑ Jones, Nigel. "पूर्णांकों का अचरों द्वारा विभाजन".
संदर्भ
- Aho, Alfred V.; Sethi, Ravi; Ullman, Jeffrey D. (1986), Compilers: Principles, Techniques, and Tools (2nd ed.), ISBN 978-0-201-10088-4
- Allen, Francis E.; Cocke, John; Kennedy, Ken (1981), "Reduction of Operator Strength", in Munchnik, Steven S.; Jones, Neil D. (eds.), Program Flow Analysis: Theory and Applications, Prentice-Hall, ISBN 978-0-13-729681-1
- Cocke, John; Kennedy, Ken (November 1977), "An algorithm for reduction of operator strength", Communications of the ACM, 20 (11): 850–856, doi:10.1145/359863.359888, S2CID 1092505
- Cooper, Keith; Simpson, Taylor; Vick, Christopher (October 1995), Operator Strength Reduction (PDF), Rice University, retrieved April 22, 2010
- Templates that generate short descriptions
- Collapse templates
- Navigational boxes
- Navigational boxes without horizontal lists
- Sidebars with styles needing conversion
- Templates generating microformats
- Templates that are not mobile friendly
- Wikipedia metatemplates
- संकलक अनुकूलन
- Machine Translated Page
- Created On 12/04/2024