gpt4 book ai didi

performance - GHC 产生冗余核心操作

转载 作者:行者123 更新时间:2023-12-03 14:51:28 28 4
gpt4 key购买 nike

我有以下用于将 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 -> Char -> Int 进行不必要的转换,或者这是代码生成不佳的一个例子?这可以优化吗?

编辑:这是使用 GHC 7.4.2,我没有尝试使用任何其他版本进行编译。此后我发现问题仍然存在于 GHC 7.6.2 中,但冗余操作已在 github 上的当前 HEAD 分支中删除。

最佳答案

Is there a reason GHC is needlessly converting from Int -> Char -> Int, or is this an example of poor code generation? Can this be optimized out?



不是真的(对两者)。您从 -ddump-simpl 获得的核心不是结束。之后在汇编代码的路上还有一些优化和转换。但在这里删除多余的转换实际上并不是一种优化。

它们可以并且已经在核心和组件之间被移除。关键是这些primops - 除了缩小之外 - 是no-ops,它们只存在于核心中,因为它是输入的。由于它们是无操作的,因此核心中是否存在它们的冗余链并不重要。

7.6.1 从代码中生成的程序集[它比 7.4.2 生成的更易读,所以我接受它] - 使用 ord而不是 to6BitASCII - 是
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它不再包含此类转换。一个字节被写入数组,一些指针/计数器递增,就是这样,跳回顶部。

我认为可以从中生成比 GHC 目前更好的代码,但是冗余的无操作转换已经消失了。

关于performance - GHC 产生冗余核心操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15095902/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com