2012-11-26 44 views
6

मैं कोड की इस पंक्ति है। मैं इस लाइन को बदलना चाहता हूं और प्रोग्राम प्रदर्शन को अधिकतम करने के लिए बिट ऑपरेशंस लागू करना चाहता हूं। मैं उसे कैसे कर सकता हूँ?मॉडुलू और डिवीजन ऑपरेटरों को बदलने के लिए बिट ऑपरेशंस का उपयोग कैसे करें?</p> <pre><code>base_num = (arr[j]/base)%256; </code></pre> <p>इस लाइन संचालन एक पाश में चलाता है और "/" और "%" संसाधनों और प्रदर्शन करने के लिए बहुत समय ले:

धन्यवाद।

+0

'आधार' स्थिर है, या यह बदलता है? – Xymostech

+9

यदि कंपाइलर कुछ भी लायक है, तो यह प्रत्येक प्लेटफॉर्म पर '% 256'' को '0xFF 'के साथ बदलता है जहां यह'% 'से तेज़ है। 'आधार' का मूल्य क्या है? –

+0

आप 'base_num' को 8 बिट (हस्ताक्षरित) पूर्णांक –

उत्तर

7

यदि आधार दो की nth शक्ति है, तो आप इसके द्वारा विभाजन को प्रतिस्थापित करने के लिए दाईं ओर विभाजित कर सकते हैं। फिर, चूंकि एक पूर्णांक का मॉड 256 लेना आखिरी 8 बिट्स लेने के बराबर है, तो आप इसे 0xFF के साथ कर सकते हैं। वैकल्पिक रूप से, आप संचालन को उलट सकते हैं यदि आप और यह 256 * बेस के साथ और फिर दाईं ओर बिट्सफ़िफ़्ट एन को दबाते हैं।

base_num = arr[j] >> n; 
base_num &= 0xFF; 

बेशक, कोई भी अर्ध-सभ्य संकलक आपके लिए ऐसा करने में सक्षम होना चाहिए।

+1

आपको 'n' बिट्स द्वारा स्थानांतरित करने की आवश्यकता है,' 2^n' '1 << n' है। –

+1

[कर्नेल जो प्रभुत्व करता है] (http://www.kernel.org) का 'पाउ' फ़ंक्शन ([glibc] से (http://ftp.gnu.org/gnu/glibc/) शीर्ष पर परिभाषित किया गया है के रूप में (सरलीकृत): 'अगर (आधार == 2) {वापसी (1 << एक्सपी)} ' –

+0

आप सही हैं, मैं इसे ठीक कर दूंगा :) –

3

-O1 या अपने कंपाइलर विकल्पों में अधिक जोड़ें और संकलक आपके लिए यह करेगा।

जीसीसी में, -O1, -ftree-slsr है जो चालू हो जाती है डॉक्स के अनुसार,

प्रदर्शन पेड़ों पर सीधे लाइन शक्ति में कमी। यह गुणाओं से जुड़े संबंधित अभिव्यक्तियों को पहचानता है और जब संभव हो तो कम महंगी गणनाओं से उन्हें बदल देता है।

यह मॉड्यूलो को बदल देगा, और आधार स्थिर होने पर। हालांकि, यदि आप जानते हैं कि आधार दो की कुछ गैर-निरंतर शक्ति होगी, तो आप उस संख्या के log2 और >> उस राशि से कम राशि के लिए आसपास के कोड को दोबारा कर सकते हैं।

1

तुम भी सिर्फ एक 8 बिट पूर्णांक के रूप में base_num घोषित कर सकता है: अपने संकलक मानकों तारीफ है

#include <stdint.h> 

uint8_t base_num; 
uint16_t crap; 
crap = 0xFF00; 
base_num = crap; 

है, यह base_num में byte(0xFF00) (0x00) का मूल्य डाल देंगे।

मैं एक संकलक कि सादा सी (न सी ++ या सी #) में गणित संतृप्त करता है को पूरा करने के लिए अभी तक है, लेकिन यदि ऐसा है, तो यह base_num में sat_byte(0xFF00) जो 0xFF से अधिक होने का मूल्य रखा जाएगा, यह 0xFF डाल देंगे।

ध्यान रखें कि आपका कंपाइलर आपको इस उदाहरण में सटीकता के नुकसान की चेतावनी देगा। आपका कंपाइलर इस मामले में त्रुटि कर सकता है (विजुअल स्टूडियो Treat Warnings as Errors चालू है)। अगर ऐसा होता है, तो आप सिर्फ कर सकते हैं:

base_num = (uint8_t)crap; 

लेकिन यह क्या आप से बचने के लिए कोशिश कर रहे हैं की तरह लगता है।

आप ऐसा करने का प्रयास कर रहे हैं ऐसा लगता है कि मॉड्यूलस ऑपरेटर को निकालना है क्योंकि इसके लिए एक विभाजन और विभाजन सबसे महंगा मूल अंकगणितीय ऑपरेशन है।मैं आम तौर पर किसी भी "बुद्धिमान" संकलक (यहां तक ​​कि डिबग मोड में) के रूप में किसी भी तरह से एक टोंटी के रूप में इस के बारे में सोच नहीं होता "का अनुकूलन" हैं यह करने के लिए:

base_num = crap & 0xFF; 
एक समर्थित मंच पर

(हर मुख्यधारा प्रोसेसर मैंने के बारे में सुना - x86, AMD64, एआरएम, एमआईपीएस), जो कोई भी होना चाहिए। मैं एक प्रोसेसर की बात सुनने के लिए डूब गया होगा जिसमें कोई बुनियादी और या अंकगणितीय निर्देश नहीं हैं।