2011-06-21 18 views
22

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

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

हमने लेबल के पते को पकड़ने के लिए इनलाइन असेंबली का उपयोग करने का प्रयास किया (और उन पर कूदने के लिए), और यह काम करता है, हालांकि, इनलाइन असेंबली का उपयोग करके पूरे कार्य को एमएसवीसी अनुकूलक से बचा जा सकता है।

क्या अनुकूलक को कोड पर अभी भी चलाने की अनुमति देने का कोई तरीका है? दुर्भाग्यवश, हम इनलाइन असेंबली में किसी अन्य फ़ंक्शन के लिए किसी लेबल को संदर्भित करने का कोई तरीका नहीं है, क्योंकि लेबल में किए गए किसी अन्य फ़ंक्शन में इनलाइन असेंबली को निकाला नहीं जा सकता है। कोई विचार या विचार? आपका इनपुट बहुत सराहना की है, धन्यवाद!

+3

क्या आपने फ़ंक्शन पॉइंटर्स का प्रयास किया है? –

+0

बाइटकोड में लेबल के पते के बजाय फ़ंक्शंस के पते डालने के बारे में कैसे? फिर आपके पास प्रत्येक निर्देश आईडी के लिए एक फ़ंक्शन है। जब तक आपका fetch-execute लूप आपके बड़े फ़ंक्शन-लेबल-लेबल में न हो। –

+0

यदि मैंने प्रत्येक मामले के लिए फ़ंक्शंस का उपयोग किया है और लेबल पते के बजाय फ़ंक्शन पॉइंटर्स का उपयोग किया है, तो यह काम करेगा।हालांकि, मुझे लगता है कि फंक्शन कॉल ओवरहेड इतना अच्छा होगा कि यह किसी भी प्रदर्शन लाभ को समाप्त कर देगा, भले ही समारोह छोटा था (कोई तर्क नहीं, कोई वापसी नहीं)। हालांकि मैं इसे कोशिश करूँगा, और पोस्ट करने के लिए धन्यवाद। – Trevor

उत्तर

15

MSVC में ऐसा करने का एक ही तरीका है इनलाइन विधानसभा (जो मूल रूप से 64 के लिए आप buggers) का उपयोग कर रहा है:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
case_1: 
    void* p; 
    __asm{ mov [p],offset case_1 } 
    printf("0x%p\n",p); 
    return 0; 
} 

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

LuaJIT is open-source, तो यदि आप उस मार्ग पर जाते हैं तो आप इससे कुछ सुझाव उठा सकते हैं। वैकल्पिक रूप से आप आगे के स्रोत को देखना चाहते हैं (जिसका निर्माता the principle विकसित करने का प्रयास कर रहा है), यदि कोई एमएसवीसी बिल्ड है तो आप देख सकते हैं कि उन्होंने इसे कैसे पूरा किया, अन्यथा आप जीसीसी (जो isn ' टी एक बुरी चीज है, यह सभी प्रमुख प्लेटफॉर्म पर काम करती है)।

3

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

परिणामस्वरूप, प्रत्येक बाइट कोड के वास्तविक कार्यान्वयन को अनुकूलित किया गया है, और बाइट कोड से machince कोड में रूपांतरण एक छोटा 1: 1 रूपांतरण है। आपको प्रत्येक कोड का विस्तार मिलता है क्योंकि प्रत्येक CALL 5 बाइट्स (x86-32 मानते हैं) लेकिन यह एक बड़ी समस्या होने की संभावना नहीं है।

9

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

http://www.erlang.org/doc/installation_guide/INSTALL-WIN32.html

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