2013-07-06 7 views
13

मानक सी फ़ंक्शन 'memcpy' कैसे काम करता है? इसे रैम के एक बड़े क्षेत्र में रैम के एक (बड़े) खंड की प्रतिलिपि बनाना है। चूंकि मुझे पता है कि आप असेंबली में रैम से राम तक सीधे नहीं जा सकते (मूव निर्देश के साथ) तो मुझे लगता है कि यह कॉपी करते समय इंटरमीडिएट मेमोरी के रूप में एक सीपीयू रजिस्टर का उपयोग करता है?memcpy काम के आंतरिक कार्यान्वयन कैसे करता है?

लेकिन यह कैसे कॉपी करता है? ब्लॉक द्वारा (यह ब्लॉक द्वारा प्रतिलिपि कैसे करेगा?), अलग-अलग बाइट्स (चार) या उनके पास सबसे बड़ा डेटा प्रकार (लंबे समय तक डबल में कॉपी करें - जो कि मेरे सिस्टम पर 12 बाइट्स है)।

संपादित करें: ठीक है जाहिरा तौर पर आप सीधे राम को राम से डेटा स्थानांतरित कर सकते हैं, मैं एक विधानसभा विशेषज्ञ नहीं हूँ और सभी मैं सीखा है विधानसभा के बारे में इस दस्तावेज़ से है (X86 assembly guide) जो mov अनुदेश के बारे में खंड में कहा गया है कि आप रैम से राम तक नहीं जा सकते हैं। जाहिर है यह सच नहीं है।

+0

यह मंच-विशिष्ट है। कृपया एक मंच निर्दिष्ट करें। –

+0

मैं लिनक्स, मैक और विंडोज़ (32-बिट, 64-बिट और 32-बिट क्रमशः) का उपयोग करता हूं लेकिन मैंने लिनक्स का उपयोग करते हुए इस सवाल से पूछा। – hddh

उत्तर

14

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

Here's a fun article जो memcpy को अनुकूलित करने में एक व्यक्ति के साहस का वर्णन करता है। मुख्य ले-होम पॉइंट यह है कि यह हमेशा उन विशिष्ट निर्देशों के आधार पर एक विशिष्ट वास्तुकला और पर्यावरण के लिए लक्षित किया जा रहा है, जिन्हें आप निष्पादित कर सकते हैं।

4

memcpy का एक तुच्छ दिया गया है:

while (n--) *s2++ = *s1++; 

लेकिन glibc आमतौर पर विधानसभा कोड में कुछ चतुर कार्यान्वयन का उपयोग करता है। memcpy कॉल आमतौर पर रेखांकित हैं।

86 पर, कोड की जाँच करता है, तो आकार पैरामीटर 2 की एक शाब्दिक एकाधिक या 4 की एक बहु (gcc builtins कार्यों का प्रयोग करके) और movl अनुदेश के साथ एक पाश का उपयोग करता है (4 बाइट्स कॉपी) अन्यथा यह सामान्य स्थिति कहते हैं।

सामान्य मामला rep और movsl निर्देशों का उपयोग कर फास्ट ब्लॉक कॉपी असेंबली का उपयोग करता है।

6

memcpy का कार्यान्वयन उस प्रणाली के लिए बेहद विशिष्ट है जिसमें इसे लागू किया गया है। कार्यान्वयन अक्सर हार्डवेयर-सहायता प्राप्त होते हैं।

मेमोरी करने वाली स्मृति mov निर्देश है कि असामान्य नहीं हैं - वे के आसपास कम से कम PDP-11 काल से किया गया है, जब आप कुछ इस तरह लिख सकते हैं:

MOV FROM, R2 
    MOV TO, R3 
    MOV R2, R4 
    ADD LEN, R4 
CP: MOV (R2+), (R3+) ; "(Rx+)" means "*Rx++" in C 
    CMP R2, R4 
    BNE CP 

टिप्पणी की लाइन मोटे तौर पर सी

के बराबर है
*to++ = *from++; 

समकालीन सीपीयू निर्देश है कि memcpy सीधे लागू है: आप स्रोत और गंतव्य पते के साथ विशेष रजिस्टरों लोड, एक स्मृति प्रतिलिपि आदेश आह्वान, और सीपीयू आराम करते हैं।

+0

"वे कम से कम पीडीपी -11 बार से आसपास रहे हैं" - बहुत लंबा। –

+0

@JimBalter यह मुझे बिल्कुल आश्चर्य नहीं करता :) – dasblinkenlight

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