首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IORef和STRef的编译

IORef和STRef的编译
EN

Stack Overflow用户
提问于 2016-08-29 09:25:46
回答 1查看 515关注 0票数 5

为了衡量这些参考文献的性能,我将GHC生成的程序集转储到以下代码中:

代码语言:javascript
复制
import Data.IORef

main = do
  r <- newIORef 18
  v <- readIORef r
  print v

我预计IORef会被完全优化,只留下一个syscall来编写字符串"18“的stdout。相反,我得到了250条生产线。你知道有多少人会被处决吗?我认为这个项目的核心是:

代码语言:javascript
复制
.globl Main.main1_info
Main.main1_info:
_c1Zi:
    leaq -8(%rbp),%rax
    cmpq %r15,%rax
    jb _c1Zj
_c1Zk:
    movq $block_c1Z9_info,-8(%rbp)
    movl $Main.main2_closure+1,%ebx
    addq $-8,%rbp
    jmp stg_newMutVar#
_c1Zn:
    movq $24,904(%r13)
    jmp stg_gc_unpt_r1
.align 8
    .long   S1Zo_srt-(block_c1Z9_info)+0
    .long   0
    .quad   0
    .quad   30064771104
block_c1Z9_info:
_c1Z9:
    addq $24,%r12
    cmpq 856(%r13),%r12
    ja _c1Zn
_c1Zm:
    movq 8(%rbx),%rax
    movq $sat_s1Z2_info,-16(%r12)
    movq %rax,(%r12)
    movl $GHC.Types.True_closure+2,%edi
    leaq -16(%r12),%rsi
    movl $GHC.IO.Handle.FD.stdout_closure,%r14d
    addq $8,%rbp
    jmp GHC.IO.Handle.Text.hPutStr2_info
_c1Zj:
    movl $Main.main1_closure,%ebx
    jmp *-8(%r13)

我很担心这个jmp stg_newMutVar#。它在程序集中没有其他地方,所以GHC可能会在稍后的链接阶段解决它。但它为什么会出现在这里,它能做什么呢?我可以在没有任何未解析的haskell符号的情况下转储最终程序集吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-29 10:23:21

从以下几个链接开始:

如果您还不熟悉cmm原目,那么原目的源代码就不是特别可读的了。不幸的是,我不知道有什么好的方法来查看为cmm primops生成的程序集,除非使用objdump或其他反汇编程序查看可执行文件。

不过,我可以总结一下IORef的运行时语义。

IORef是来自GHC.PrimMutVar#的包装器。正如医生所说,MutVar#就像一个单元素可变数组.它占用两个机器单词,第一个是头,第二个是存储的值(它是指向GHC对象的指针)。MutVar#的值本身就是指向这个双单词对象的指针。

MutVar-s与普通的不可变对象不同,最显著的是参与了写屏障机制。GHC具有分代垃圾收集功能,因此在收集年轻一代时,任何生活在老一代的MutVar都必须是GC根,因为变异MutVar可能会使较年轻的对象变得可访问。因此,每当从第0代(最小的)提升MutVar时,就会将其添加到所谓的“可变列表”中,其中包含对所有此类可变对象的引用。可变列表在老一代的GC中重新生成。简而言之,老一代的MutVar-s总是出现在可变列表上。

这是处理可变变量的一种相当简单的方法,如果在老一代中有大量可变变量,那么小型垃圾收集就会因为庞大的可变列表而减慢速度,因此导致整个程序慢下来

由于可变变量在生产代码中没有显着地使用,因此没有太多的需求或压力来优化RTS,因为它们的大量使用。

如果需要大量可变变量,则应该使用单个可变框数组,因为这只是可变列表上的单个引用,而且还具有一个位图优化,用于遍历可能已发生变异的元素。

而且,正如您所看到的,newMutVar#只是静态链接,而不是内联,尽管它是一个相当小的代码块。因此,它也没有被优化掉。这在很大程度上是由于对优化变异代码缺乏努力和关注。相比之下,分配和复制小型已知大小的基元数组目前是内嵌,并且进行了很大的优化,因为约翰·蒂贝尔在实现unordered-containers库时做了大量工作(以便使unordered-containers更快)。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39202738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档