2012-08-01 13 views
6

<<= से सस्ता (तेज़) है, और इसी तरह >>= से सस्ता (तेज़) है?कौन सा ऑपरेटर तेज है (> या> =), (<या <=)?

अस्वीकरण: मुझे पता है कि मैं माप सकता हूं लेकिन यह केवल मेरी मशीन पर होगा और मुझे यकीन नहीं है कि उत्तर "कार्यान्वयन विशिष्ट" या ऐसा कुछ हो सकता है या नहीं।

+12

मुझे लगता है कि वे दोनों आर्किटेक्चर में एक ही निर्देश के लिए संकलित हैं, लेकिन जवाब है: कौन परवाह करता है? – meagar

+1

यदि आप यही पूछते हैं तो वे असेंबली निर्देशों के मामले में लगभग बराबर हैं। –

+8

मैं आपके प्रश्न के पीछे की भावना को समझता हूं, लेकिन: क्या आप इसे अकादमिक हित से पूछते हैं, या क्योंकि आपको लगता है कि इससे आपके ऐप के प्रदर्शन पर असर पड़ सकता है? यह नहीं होगा अंतर, यदि मौजूद है, तो आपके ऐप के अन्य कारकों द्वारा ** ** ** पूरी तरह से ** मुद्रित होगा। 2, या 10 के कारक से नहीं, लेकिन 1 मीटर या उससे अधिक तक। मैं शर्त लगाऊंगा कि आप इसे मापने में सक्षम नहीं होंगे। –

उत्तर

3

यह भिन्न होता है, पहले विभिन्न निर्देश सेटों की जांच करने और कंप्यूटर्स उन निर्देश सेटों का उपयोग कैसे करते हैं। उदाहरण के लिए ओपन्रिस्क 32 लें, जो स्पष्ट रूप से प्रेरित प्रेरित है लेकिन सशर्त अलग-अलग करता है। Or32 के लिए तुलना और ध्वज निर्देश सेट करें, इन दो रजिस्टरों की तुलना करें यदि हस्ताक्षर से कम या बराबर है तो ध्वज सेट करें, ध्वज सेट करने के बराबर इन दो रजिस्टरों की तुलना करें। फिर झंडा सेट पर फ्लैग सेट और शाखा पर दो सशर्त शाखा निर्देश शाखाएं हैं। कंपाइलर को इन पथों में से एक का पालन करना होता है, लेकिन उससे कम, बराबर या बराबर, उससे अधिक, आदि, समान संख्या में निर्देशों का उपयोग करने जा रहे हैं, सशर्त शाखा के लिए एक ही निष्पादन समय और समान निष्पादन समय नहीं कर रहे हैं सशर्त शाखा

अब यह निश्चित रूप से सच है कि अधिकांश आर्किटेक्चर के लिए यह सच होने जा रहा है कि शाखा को फ्लश करने और फिर से भरने के कारण शाखा को निष्पादित करने से अधिक समय लगता है। कुछ समस्या की सहायता के लिए शाखा भविष्यवाणी आदि करते हैं।

अब कुछ आर्किटेक्चर निर्देश के आकार में भिन्न हो सकते हैं, gpr0 और gpr1 की तुलना gpr0 की तुलना करें और तत्काल संख्या 1234 की तुलना करें, एक बड़े निर्देश की आवश्यकता हो सकती है, उदाहरण के लिए आप इसे x86 के साथ बहुत कुछ देखेंगे।इसलिए यदि दोनों रजिस्टरों के प्रदर्शन के अंतर के आधार पर कम से कम एन्कोड करने के तरीके से कम हो, तो दोनों मामले एक शाखा हो सकते हैं (निश्चित x86 इन समस्याओं के लिए बनाने के लिए बहुत सी पाइपलाइनिंग, कैशिंग के बहुत सारे आदि करता है))। एक और इसी तरह का उदाहरण मिप्स और ओ 32 है, जहां आर 0 हमेशा शून्य होता है, यह वास्तव में एक सामान्य उद्देश्य रजिस्टर नहीं है, अगर आप इसे लिखते हैं तो यह नहीं बदलता है, यह शून्य के लिए कड़ी मेहनत की जाती है, इसलिए यदि तुलना 0 मीटर के बराबर हो तो तुलना करें तुलनात्मक से अधिक यदि किसी अन्य नंबर के बराबर है तो एक अतिरिक्त निर्देश या दो को तत्काल के साथ एक जीआरपी भरने की आवश्यकता होती है ताकि तुलना हो सके, सबसे खराब मामला स्टैक या मेमोरी में रजिस्टर को बेदखल कर रहा है, वहां तत्काल रखने के लिए पंजीकरण करें ताकि तुलना हो सके।

कुछ आर्किटेक्चर बांह के लिए छद्म कोड

होगा, पूर्ण भुजा (नहीं अंगूठे) निर्देश के लिए आप एक प्रति अनुदेश के आधार पर निष्पादित कर सकते हैं हाथ की तरह सशर्त निष्पादन है, इसलिए यदि आप कोड

if(i==7) j=5; else j=9; 

था

cmp i,#7 
moveq j,#5 
movne j,#7 

कोई वास्तविक शाखा नहीं है, इसलिए कोई पाइपलाइन समस्याएं आप बहुत तेज़ी से उड़ते हैं।

किसी अन्य के लिए एक आर्किटेक्चर यदि यह उल्लेख किया गया है कि कुछ उल्लेखनीय है, तो एमआईपीएस, या 32, आपको विशेष रूप से तुलना के लिए कुछ प्रकार के निर्देश करना है, जैसे x86, msp430 और विशाल बहुमत प्रत्येक अलू ऑपरेशन झंडे को बदलता है , हाथ और जैसे परिवर्तन झंडे अगर आप इसे झंडे को बदलने के लिए कहते हैं अन्यथा ऊपर दिखाए गए अनुसार नहीं। तो एक

while(--len) 
{ 
    //do something 
} 

पाश 1 को निकाल दिया भी झंडे सेट, अगर पाश में सामान काफी सरल आप पूरी बात सशर्त बना सकता था, इसलिए आप अलग तुलना और शाखा निर्देश पर बचाने के लिए और आप में बचाने के पाइपलाइन जुर्माना। मिप्स इसकी तुलना करके थोड़ा सा हल करता है और शाखा एक निर्देश है, और वे पाइप में थोड़ा बचाने के लिए शाखा के बाद एक निर्देश निष्पादित करते हैं।

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

10

टी एल; डॉ

वहाँ प्रतीत होता है छोटे-से-चार ऑपरेटरों के बीच का अंतर, वे सब मेरे लिए एक ही समय (विभिन्न प्रणालियों पर अलग हो सकता है!) के बारे में में प्रदर्शन के रूप में। इसलिए, जब संदेह हो, तो ऑपरेटर का उपयोग करें जो स्थिति के लिए सबसे अधिक समझ में आता है (विशेष रूप से जब सी ++ के साथ गड़बड़ हो)।

मान लिया जाये कि पूर्णांक तुलना:

जहां तक ​​विधानसभा उत्पन्न, परिणाम मंच निर्भर कर रहे हैं

तो, आगे की हलचल के बिना, यहाँ लंबे व्याख्या है। अपने कंप्यूटर (एप्पल LLVM संकलक 4.0, x86_64), परिणामों पर (इस प्रकार उत्पन्न विधानसभा है):

a < b (uses 'setl'): 

movl $10, -8(%rbp) 
movl $15, -12(%rbp) 
movl -8(%rbp), %eax 
cmpl -12(%rbp), %eax 
setl %cl 
andb $1, %cl 
movzbl %cl, %eax 
popq %rbp 
ret 

a <= b (uses 'setle'): 

movl $10, -8(%rbp) 
movl $15, -12(%rbp) 
movl -8(%rbp), %eax 
cmpl -12(%rbp), %eax 
setle %cl 
andb $1, %cl 
movzbl %cl, %eax 
popq %rbp 
ret 

a > b (uses 'setg'): 

movl $10, -8(%rbp) 
movl $15, -12(%rbp) 
movl -8(%rbp), %eax 
cmpl -12(%rbp), %eax 
setg %cl 
andb $1, %cl 
movzbl %cl, %eax 
popq %rbp 
ret 

a >= b (uses 'setge'): 

movl $10, -8(%rbp) 
movl $15, -12(%rbp) 
movl -8(%rbp), %eax 
cmpl -12(%rbp), %eax 
setge %cl 
andb $1, %cl 
movzbl %cl, %eax 
popq %rbp 
ret 

कौन वास्तव में मुझे ज्यादा नहीं बता रही है। तो, हम एक बेंचमार्क पर जाते हैं:

और महिलाओं & सज्जनो, परिणाम हैं, मैंने निम्नलिखित परीक्षण कार्यक्रम बनाया है (मुझे पता है कि 'घड़ी' इस तरह के परिणामों की गणना करने का सबसे अच्छा तरीका नहीं है, लेकिन यह अब के लिए करना होगा)।

#include <time.h> 
#include <stdio.h> 

#define ITERS 100000000 

int v = 0; 

void testL() 
{ 
    clock_t start = clock(); 

    v = 0; 

    for (int i = 0; i < ITERS; i++) { 
     v = i < v; 
    } 

    printf("%s: %lu\n", __FUNCTION__, clock() - start); 
} 

void testLE() 
{ 
    clock_t start = clock(); 

    v = 0; 

    for (int i = 0; i < ITERS; i++) 
    { 
     v = i <= v; 
    } 

    printf("%s: %lu\n", __FUNCTION__, clock() - start); 
} 

void testG() 
{ 
    clock_t start = clock(); 

    v = 0; 

    for (int i = 0; i < ITERS; i++) { 
     v = i > v; 
    } 

    printf("%s: %lu\n", __FUNCTION__, clock() - start); 
} 

void testGE() 
{ 
    clock_t start = clock(); 

    v = 0; 

    for (int i = 0; i < ITERS; i++) { 
     v = i >= v; 
    } 

    printf("%s: %lu\n", __FUNCTION__, clock() - start); 
} 

int main() 
{ 
    testL(); 
    testLE(); 
    testG(); 
    testGE(); 
} 

कौन सा, मेरी मशीन (-O0 साथ संकलित) पर, मुझे इस (5 अलग रन) देता है:

 
testL: 337848 
testLE: 338237 
testG: 337888 
testGE: 337787 

testL: 337768 
testLE: 338110 
testG: 337406 
testGE: 337926 

testL: 338958 
testLE: 338948 
testG: 337705 
testGE: 337829 

testL: 339805 
testLE: 339634 
testG: 337413 
testGE: 337900 

testL: 340490 
testLE: 339030 
testG: 337298 
testGE: 337593 

मैं तर्क है कि इन ऑपरेटरों के बीच मतभेद पर सबसे अच्छा छोटे हैं, और डॉन एक आधुनिक कंप्यूटिंग दुनिया में ज्यादा वजन नहीं है।

+3

असेंबली कोड वास्तव में बहुत कुछ बता रहा था। यह कह रहा था कि उन सभी स्निपेटों को एक ही समय में लेना चाहिए, सभी परिस्थितियों के बराबर होना चाहिए। 'सीसीसी' क्या है, इस पर ध्यान दिए बिना 'सेटसीसी' 1 चक्र लेता है (पी 4 को छोड़कर, जहां यह 3 लेता है)। लेकिन यह भी प्रासंगिक कैसे है? तुलना ऑपरेटर लगभग इस तरह से कभी नहीं उपयोग किए जाते हैं - 'जेसीसी' के प्रदर्शन की तुलना करना ('सीसी' के बावजूद भी) अधिक तार्किक लगता है। – harold

+1

मैं दूसरा @हरोल्ड। असेंबली बहुत कुछ बता रही है - सभी तुलना एक ही 'सीएमपीएल' निर्देश का उपयोग करके की जाती है जो इसके तर्कों की तुलना करने के भारी भारोत्तोलन करती है। असल में यह पहले तर्क (परिणाम को छोड़कर) से दूसरे तर्क को घटा देता है और एएलयू झंडे रजिस्टर में संबंधित बिट सेट करता है। इन्हें फिर परीक्षण किया जा सकता है, मेमोरी/रेग मान सेट करने के लिए इस्तेमाल किया जा सकता है या इस्तेमाल किया जा सकता है। –

+1

@harold वह शायद "यह _me_ ज्यादा नहीं बता रहा है" – hirschhornsalz