2013-02-26 40 views
16

मेरे पास 6 बिट ASCII को बाइनरी प्रारूप में परिवर्तित करने के लिए निम्न प्रोग्राम है।जीएचसी जेनरेटिंग रिडंडेंट कोर ऑपरेशंस

ascii2bin :: Char -> B.ByteString 
ascii2bin = B.reverse . fst . B.unfoldrN 6 decomp . to6BitASCII -- replace to6BitASCII with ord if you want to compile this 
    where decomp n = case quotRem n 2 of (q,r) -> Just (chr r,q) 

bs2bin :: B.ByteString -> B.ByteString 
bs2bin = B.concatMap ascii2bin 

इस निम्नलिखित मुख्य खंड का उत्पादन:

Rec { 
$wa 
$wa = 
    \ ww ww1 ww2 w -> 
    case ww2 of wild { 
     __DEFAULT -> 
     let { 
      wild2 
      wild2 = remInt# ww1 2 } in 
     case leWord# (int2Word# wild2) (__word 1114111) of _ { 
      False -> (lvl2 wild2) `cast` ...;                     
      True -> 
      case writeWord8OffAddr# 
        ww 0 (narrow8Word# (int2Word# (ord# (chr# wild2)))) w 
      of s2 { __DEFAULT -> 
      $wa (plusAddr# ww 1) (quotInt# ww1 2) (+# wild 1) s2 
      } 
     }; 
     6 -> (# w, (lvl, lvl1, Just (I# ww1)) #) 
    } 
end Rec } 

सूचना है कि ord . chr == id, और इसलिए वहाँ एक अनावश्यक यहाँ ऑपरेशन है: narrow8Word# (int2Word# (ord# (chr# wild2)))

एक कारण GHC बेकार में इंट से परिवर्तित किया जाता है है - > चार -> Int, या यह खराब कोड पीढ़ी का एक उदाहरण है? क्या इसे अनुकूलित किया जा सकता है?

संपादित करें: यह जीएचसी 7.4.2 का उपयोग कर रहा है, मैंने किसी भी अन्य संस्करण के साथ संकलन करने की कोशिश नहीं की है। मुझे तब से पता चला है कि समस्या जीएचसी 7.6.2 में बनी हुई है, लेकिन अनावश्यक परिचालन जिथब पर मौजूदा हेड शाखा में हटा दिए जाते हैं।

उत्तर

19

क्या कोई कारण है कि जीएचसी Int -> Char -> Int से अविश्वसनीय रूप से परिवर्तित हो रहा है, या यह खराब कोड पीढ़ी का एक उदाहरण है? क्या इसे अनुकूलित किया जा सकता है?

वास्तव में नहीं (दोनों को)। -ddump-simpl से प्राप्त कोर अंत नहीं है। असेंबली कोड के रास्ते पर कुछ अनुकूलन और परिवर्तन अभी भी किए गए हैं। लेकिन यहां अनावश्यक रूपांतरणों को हटाने वास्तव में एक अनुकूलन नहीं है।

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

विधानसभा कि 7.6.1 कोड से पैदा करता है [यह क्या 7.4.2 पैदा करता है की तुलना में अधिक पठनीय है, तो मैं ले कि] - ordto6BitASCII के बजाय साथ -

ASCII.$wa_info: 
_cXT: 
    addq $64,%r12 
    cmpq 144(%r13),%r12 
    ja _cXX 
    movq %rdi,%rcx 
    cmpq $6,%rdi 
    jne _cXZ 
    movq $GHC.Types.I#_con_info,-56(%r12) 
    movq %rsi,-48(%r12) 
    movq $Data.Maybe.Just_con_info,-40(%r12) 
    leaq -55(%r12),%rax 
    movq %rax,-32(%r12) 
    movq $(,,)_con_info,-24(%r12) 
    movq $lvl1_rVq_closure+1,-16(%r12) 
    movq $lvl_rVp_closure+1,-8(%r12) 
    leaq -38(%r12),%rax 
    movq %rax,0(%r12) 
    leaq -23(%r12),%rbx 
    jmp *0(%rbp) 
_cXX: 
    movq $64,192(%r13) 
_cXV: 
    movl $ASCII.$wa_closure,%ebx 
    jmp *-8(%r13) 
_cXZ: 
    movl $2,%ebx 
    movq %rsi,%rax 
    cqto 
    idivq %rbx 
    movq %rax,%rsi 
    cmpq $1114111,%rdx 
    jbe _cY2 
    movq %rdx,%r14 
    addq $-64,%r12 
    jmp GHC.Char.chr2_info 
_cY2: 
    movb %dl,(%r14) 
    incq %r14 
    leaq 1(%rcx),%rdi 
    addq $-64,%r12 
    jmp ASCII.$wa_info 
    .size ASCII.$wa_info, .-ASCII.$wa_info 

हिस्सा है जहां narrow8Word# (int2Word# (ord# (chr# wild2))) है कोर में दिखाई देता है cmpq $1114111, %rdx के बाद। यदि मात्रात्मक सीमा से बाहर नहीं है, तो कोड _cY2 पर कूदता है जिसमें अब कोई रूपांतरण नहीं है। एक बाइट सरणी में लिखा जाता है, कुछ पॉइंटर्स/काउंटर बढ़ते हैं, और यही वह है, शीर्ष पर वापस जाएं।

मुझे लगता है कि वर्तमान में जीएचसी की तुलना में बेहतर कोड उत्पन्न करना संभव होगा, लेकिन अनावश्यक नो-ऑप रूपांतरण पहले ही गायब हो गए हैं।

+2

हाँ, ठीक है। इनमें से अधिकतर मूल्य स्तर पर मौजूद हैं जो केवल प्रकारों को बदलने के लिए मौजूद हैं। चूंकि कोर टाइप किया गया है, यह आवश्यक है। –

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