2010-09-17 3 views
5

मैं इस कार्य को पूरा करने के कुछ ग़लत अक्षम तरीकों के बारे में सोच सकता हूं, लेकिन मुझे आश्चर्य है कि सबसे अच्छा तरीका क्या है।स्रोत से स्मृति की प्रतिलिपि कैसे करें जो बाइट संरेखण (स्थानांतरित) पर नहीं है

उदाहरण के लिए मैं एक बाइट में तीसरे बिट से शुरू होने वाली 10 बाइट कॉपी करना चाहता हूं और सामान्य रूप से पॉइंटर पर प्रतिलिपि बनाना चाहता हूं।

क्या एक समय में एक स्थानांतरित बाइट की प्रतिलिपि बनाने का बेहतर तरीका है?

धन्यवाद

+0

और आप ऐसा क्यों करना चाहते हैं? –

+0

@ एडम: ऐसा होता है! – SamB

+0

हां @ एसएएमबी ने क्या कहा। मैं कम मेमोरी सिस्टम के साथ काम कर रहा हूं, और कुछ कसकर पैक किया गया डेटा मिला। यहां तक ​​कि अगर यह समझ में नहीं आता है तो भी मुझे सवाल पूछने की तरह लगा। – Ryu

उत्तर

5

सामान्य दृष्टिकोण स्रोत बफर को यथासंभव कुशलता से पढ़ना है, और इसे गंतव्य बफर लिखने के तरीके के रूप में आवश्यक स्थानांतरित करना है।

आपको बाइट ऑपरेशंस करने की ज़रूरत नहीं है, आप हमेशा स्रोत को long पढ़ सकते हैं, शुरुआत में तीन बाइट्स तक ऑपरेशन के बड़े हिस्से के लिए गठबंधन किया जाता है, और इसी तरह अंत को संभालने के बाद से आपको प्रयास नहीं करना चाहिए निर्दिष्ट स्रोत बफर लंबाई पिछले पढ़ने के लिए।

मूल्यों को पढ़ने से, आप वांछित बिट संरेखण प्राप्त करने के लिए आवश्यक स्थानांतरित कर सकते हैं और गंतव्य पर लिखने के लिए समाप्त बाइट इकट्ठा कर सकते हैं। आप सबसे व्यापक गठबंधन शब्द आकार को लिखने के समान अनुकूलन भी कर सकते हैं।

यदि आप स्रोत में चारों ओर एक संपीड़न उपकरण या लाइब्रेरी में खोदते हैं जो चर-चौड़ाई टोकन (zlib, एमपीईजी, टीआईएफएफ, और जेपीईजी सभी दिमाग में छलांग लगाने) का व्यापक उपयोग करता है तो आपको संभवतः एक इनपुट के साथ नमूना कोड मिल जाएगा या बिट्स की धारा के रूप में आउटपुट बफर जिसमें कुछ कार्यान्वयन विचार होंगे, इसके बारे में सोचने के लिए।

0

यह समाधान मैं कोडित, और उपयोग शुरू कर दिया है।

void RightShiftMemCopy(uchar * pSource, uchar * pDest ,ushort len,uchar shiftOffset) 
{ 
    ushort i=0; 

    pDest+=(len-1); 
    pSource+=(len-1); 

    for(i=len-1;i != 0 ;--i) 
    { 
     *pDest = (*(pSource - 1) << 8 | *pSource) >> shiftOffset; 

     --pDest; 
     --pSource; 
    } 

    *pDest = *pSource >> shiftOffset; 

} 
+0

एक बाइट की प्रतिलिपि बनाने के लिए 'memcpy() 'को कॉल न करें। बस 'destData [i] = val' कहें। यहां 'pSource' का उपयोग नाम की एक खराब पसंद है। और 'memcpy' कॉल में इसका उपयोग एक विशेष अंतराल मानता है। – RBerteig

3

x86 पर आप जिस छोटी इकाई को एक्सेस कर सकते हैं वह बाइट है। हालांकि आप एक समय में 4 बाइट्स तक पहुंच सकते हैं और एक बाइट की बजाय एक समय में 4 बाइट्स के साथ काम कर सकते हैं। अधिक गति के लिए आप pslldq (SSE2) का उपयोग कर सकते हैं। बेशक, सुनिश्चित करें कि आप प्रतियां अधिकतम प्रदर्शन के लिए गठबंधन हैं।

+1

क्या पूछताछ करने वाले के साथ कुछ लेना देना नहीं है। वह उस डेटा की प्रतिलिपि बनाना चाहता है जिसमें उप-बाइट संरेखण है, आप उसे बता रहे हैं कि उसके पास पहले से मौजूद एक बदतर 'memcpy' को कैसे कार्यान्वित किया जाए। – SamB

+2

@ सैमबी: वास्तव में नहीं। एक समय में पूरे शब्दों को बिछाते हुए एक बार में एक बाइट करने से बहुत तेज़ होगा। –

+0

हाँ - @ आर सही है। बहुत तेज़ आप प्रति निर्देश चक्र देख सकते हैं। चलो निष्कर्ष लोगों के लिए कूद नहीं है। – EdH

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