【问题标题】:Memory layout of boxed and unboxed ints? [duplicate]装箱和未装箱整数的内存布局? [复制]
【发布时间】:2013-06-25 16:35:36
【问题描述】:

我的理解是,Int 值是指向 thunk(双重间接)的指针,而未装箱的 Int# 只是指向 32/64 位 int 的指针。那是对的吗?指针如何对它引用未装箱值的事实进行编码?

Haskell standard 声明 Int 是“至少具有 [-2^29 .. 2^29-1] 范围的固定精度整数类型”。 GHC 中是否有一些优化,其中这些额外的位用于消除间接性?

【问题讨论】:

标签: haskell ghc


【解决方案1】:

GHC documentation 有一些很好的信息。但基本上,您说 Int 值是指向 thunk 的指针是正确的。但是,未装箱值不是指向未装箱值的指针,它未装箱值本身。此外,Haskell 标准报告仅给出了Int 范围的下限。 IIRC、GHC Int 有超过 30 位。

我不认为 GHC 使用未装箱类型的额外位来存储任何元数据,但它确实使用指针位来这样做。有关详细信息,请参阅this 页面。

【讨论】:

  • 正确。在 GHC 中,Int 往往是 32 位(例如:在 x86 系统上)或 64 位(例如:在 x86_64 上)。如果 29、32 和 64 位 Ints 之间的区别很重要,那么用户应该利用 Int32Int64 或 Integer。
  • 信息在类型(和种类)中——一个未装箱的 Int 在 GHC 中具有类型 Int#,并且是二等公民(例如,您不能将它传递给多态函数直接,因为多态函数需要一个装箱的值)。
  • 当你有一个解压的 strict Int —— 如在 data Foo = Foo {-# UNPACKED #-} !Int —— 它也将被拆箱存储,直接作为 Foo 值的一部分。但是 GHC 会在必要时透明地装箱和拆箱,因此您通常不必担心这一点。 (并且该信息在编译时再次为人所知。)
  • 它本身根本不需要存储;编译后的代码已经知道什么是装箱的,什么是拆箱的。
  • @DanielVelkov 在 GHC 中,未装箱的整数是二等公民,您不能将它们传递给多态函数。 (您可以将指针传递给它们,然后将它们是不被遍历的整数的信息存储在指向块的标题中)。特别是,它们只能在编译器静态知道它们存在的地方流动,并为它们生成正确的 GC 处理代码。 OCaml整数可以传递给多态函数,所以多态函数不能静态知道它的参数值是整数还是指针,它需要一个标签。
猜你喜欢
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
相关资源
最近更新 更多