2010-10-03 26 views
9

मैं डीकोड में एक प्रोग्राम के निष्पादन के दौरान व्यावहारिक अंतर को समझने की कोशिश कर रहा हूं और व्याख्या को प्रेषित करता हूं और थ्रेड व्याख्याडीकोड और व्याख्या को बनाम बनाम बनाम बनाम

दोनों का उदाहरण वास्तव में मदद करेगा।

मैं समझता हूं कि जावा बाइटकोड कैसे काम करता है और कैसे एक असेंबली भाषा काम करती है। लेकिन डीडीआई और टीआई कहाँ फिट बैठता है?

प्रसंग: Virtual machines: versatile platforms for systems and processes

उत्तर

17

(नोट: मैं मान लेंगे कि "डिकोड और प्रेषण" द्वारा आप एक स्विच आधारित दुभाषिया मतलब है।)

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

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

typedef enum { 
    add, /* ... */ 
} instruction_t; 

void interpret() { 
    static instruction_t program[] = { add /* ... */ }; 
    instruction_t* pc = program; 
    int* sp = ...; /* stack pointer */ 
    for (;;) { 
    switch (*pc++) { 
     case add: 
     sp[1] += sp[0]; 
     sp++; 
     break; 
     /* ... other instructions */ 
    } 
    } 
} 

एक लड़ी दुभाषिया में, डिकोडिंग कोड केंद्रीकृत नहीं, बल्कि कोड के प्रत्येक टुकड़े कि एक अनुदेश हैंडल के अंत में दोहराया गया है। इसका मतलब यह है कि एक बार एक निर्देश का अर्थ लिया गया है, कुछ केंद्रीकृत डिकोडिंग कोड पर वापस कूदने के बजाय, दुभाषिया अगले निर्देश को डीकोड करता है और तुरंत इसे कूदता है। एएनएसआई-सी में कुशलता से थ्रेडेड कोड को कार्यान्वित करना वास्तव में संभव नहीं है, लेकिन जीसीसी का "संगणित गोटो" एक्सटेंशन इसके लिए बहुत अच्छा काम करता है। यहाँ पिछले दुभाषिया की एक लड़ी संस्करण है:

void interpret() { 
    void* program[] = { &&l_add, /* ... */ }; 
    int* sp = ...; 
    void** pc = program; 
    goto **pc; /* jump to first instruction */ 
l_add: 
    sp[1] += sp[0]; 
    ++sp; 
    goto **(++pc); /* jump to next instruction */ 
    /* ... other instructions */ 
} 

अलावा एक कूद बचत से, इस तरह के थ्रेडेड दुभाषिए भी अधिक कुशल क्योंकि दोहराया अप्रत्यक्ष कूद (अगले निर्देश के लिए) आधुनिक CPUs से बेहतर भविष्यवाणी की जा सकती है। एंटोन एर्टल के पास his home page पर कुछ दिलचस्प कागजात हैं, विशेष रूप से "संरचना और कुशल दुभाषियों का प्रदर्शन" नामक एक व्यक्ति, जिसमें कोड के उपरोक्त टुकड़े अनुकूलित किए गए थे।

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