2011-04-11 16 views
5

मेरी प्रोजेक्ट में एक वीएम है जो डोमेन-विशिष्ट-भाषा से संकलित बाइट-कोड निष्पादित करता है। मैं उन तरीकों को देख रहा हूं कि मैं बाइट-कोड के निष्पादन समय को बेहतर बना सकता हूं। पहले चरण के रूप में मैं यह देखना चाहता हूं कि मशीन कोड संकलन में प्रवेश करने से पहले बाइट-कोड दुभाषिया को सुधारने का कोई तरीका है या नहीं।इष्टतम वर्चुअल मशीन/बाइट-कोड दुभाषिया लूप

दुभाषिया के मुख्य पाश इस तरह दिखता है:

while(true) 
{ 
    uint8_t cmd = *code++; 
    switch(cmd) 
    { 
    case op_1: ...; break; 
    ... 
    } 
} 

प्रश्न: वहाँ कोडांतरक का सहारा के बिना इस पाश लागू करने के लिए एक तेजी से रास्ता नहीं है?

एक विकल्प जो मैं देखता हूं वह जीसीसी विशिष्ट है जो लेबल पते के साथ गतिशील गोटो का उपयोग करने के लिए विशिष्ट है। प्रत्येक मामले के अंत में break की बजाय मैं सीधे अगले निर्देश पर कूद सकता था। मैंने आशा की थी कि ऑप्टिमाइज़र मेरे लिए ऐसा करेगा, लेकिन डिस्सेप्लर को देखकर यह स्पष्ट रूप से नहीं करता है: अधिकांश op_codes के अंत में लगातार दोहराया जाता है।

यदि प्रासंगिक वीएम एक साधारण रजिस्टर आधारित मशीन है जिसमें फ्लोटिंग पॉइंट और पूर्णांक रजिस्ट्रार (प्रत्येक में से 8) हैं। कोई ढेर नहीं है, केवल एक वैश्विक ढेर (वह भाषा जटिल नहीं है)।

उत्तर

3

एक बहुत ही आसान अनुकूलन कि बजाय स्विच/मामले/मामले/मामले/मामले/मामले,

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

switch(cmd) 

के बजाय सिर्फ एक

करना

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

यदि आप ऐसा नहीं करेंगे, कम से कम उन आदेशों को सॉर्ट करें जो सबसे अधिक इस्तेमाल किए गए स्विच कथन की शुरुआत में हैं।

अन्यथा यह हैशटेबल्स को देखना होगा, लेकिन मुझे लगता है कि आपके पास बहुत से आदेश नहीं हैं, और उस स्थिति में हैश फ़ंक्शन करने के ऊपरी हिस्से में शायद आपको स्विच करने से अधिक खर्च नहीं होगा। (या बहुत सरल हैश फ़ंक्शन)

+1

यह बेहद असंभव है कि स्विच की बजाय फ़ंक्शन कॉल करना तेज होगा (फ़ंक्शन कॉल का एक महत्वपूर्ण ओवरहेड होगा)। स्विच किसी भी तरह से कूद-टेबल पर शिकायत कर रहा है (जीसीसी कम से कम करता है)। –

+0

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

+1

आप प्रेषण तालिका के माध्यम से किए गए कॉल इनलाइन नहीं कर सकते हैं। यहां सबसे नज़दीकी विकल्प जीसीसी लेबल पते का उपयोग करना है, जो मूल रूप से आपको एक जंप टेबल में अपने इनलाइन फ़ंक्शंस बनाने देता है। –

1

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

+0

x86_64। यह निश्चित रूप से मेरे कोड आकार को गुब्बारा देगा, लेकिन कोड काफी छोटा है। –

+0

दूसरे विचार पर यह काम नहीं कर सकता क्योंकि कोड इनलाइन डेटा (स्थिरांक) के साथ interleaved है। संरेखण को रखने के लिए सब कुछ 8bytes तक बढ़ना होगा। यह काफी महंगा होगा (मैं इसे वैसे भी कोशिश करूंगा)। –

+0

नहीं, शून्य गति वृद्धि। –

-1

कुछ स्पष्ट अनुकूलन मैं कर रहे हैं,

  1. आप cmdswitch() से कहीं भी तो उपयोग नहीं करते हैं, सीधे सूचक अविवेक का उपयोग करें, switch(*code++)while(true) लूप के लिए, यह थोड़ा सहायक हो सकता है।
  2. switch() में, आप break के बजाय continue का उपयोग कर सकते हैं।क्योंकि continueif/else या switch के अंदर उपयोग किया जाता है, इसलिए संकलक जानता है कि निष्पादन बाहरी लूप पर कूदना है; break (switch के संबंध में) के लिए भी यह सच नहीं है। उम्मीद है कि यह मदद करता है।
+0

प्वाइंट 1 मैंने पहले कोशिश की और इससे कोई फर्क नहीं पड़ता (ऑप्टिमाइज़र संभवतः इसे वही देखता है)। प्वाइंट 2 मैं वास्तव में करता हूं, ऐसा लगता है कि यह बहुत ही मामूली अंतर बनाता है (अजीब है कि ऑप्टिमाइज़र स्वयं ही ऐसा नहीं करेगा, लेकिन समय अंतर इतना छोटा है कि सांख्यिकीय विसंगति को रद्द करना मुश्किल है)। –

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