加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 为什么某些类型(例如Float80)的内存对齐大于字大小?

发布时间:2020-12-14 04:47:40 所属栏目:百科 来源:网络整理
导读:为了使它具体,我只想知道为什么在我的64位mac上,Swift编译器说某些类型如Float80的对齐是16. 要检查类型的内存对齐要求,我使用alignof函数. sizeof(Float80) // ~ 16 bytes,it only needs 10 bytes,but because of hardware design decisions it has to be a
为了使它具体,我只想知道为什么在我的64位mac上,Swift编译器说某些类型如Float80的对齐是16.
要检查类型的内存对齐要求,我使用alignof函数.

sizeof(Float80) // ~> 16 bytes,it only needs 10 bytes,but because of hardware design decisions it has to be a power of 2
strideof(Float80) // ~> 16 bytes,clear because it is exact on a power of 2,struct types with Float80 in it,can be bigger
alignof(Float80) // ~> 16 bytes,why not 8 bytes,like String ?

我理解类型的内存对齐小于或等于单词的大小是有益的.

sizeof(String) // ~> 24 bytes,clear because 24 is multiple of 8
strideof(String) // ~> 24 bytes,clear because 24 is multiple of 8
alignof(String) // ~> 8 bytes,clear because something greater or equal to 8 bytes should align to 8 bytes

许多具有较大内存大小的足迹(如String(大小为24))确实具有8字节的内存对齐要求.我希望这是我正在使用的CPU / RAM总线的大小,因为我有一个64位的mac和os.
我检查了类型的大小,没有使用sizeof函数的最后一个填充,并且使用strideof函数添加填充到末尾(strideof在结构数组中更有用,然后Swift在末尾添加字节以达到下一个倍数对齐要求.)

我知道填充对于小于或等于8字节大小的类型是必要的.

但我不明白为什么在我的64位mac上有一个大于8字节的内存对齐要求是有利的.

Float80的值需要80位,即10个字节,有6个填充字节.

这是一张图片,使其更加清晰,我的意思.
Float80允许绿色位置,红色位置不允许.
该图中的内存为8字节块.

解决方法

所有“原始数据类型”(该术语可能是错误的,我的意思是
处理器使用的数据类型具有“自然边界”,
并且编译器会相应地将它们对齐在内存中.对齐
取决于处理器(例如x86或ARM)和编程环境(例如32位与64位).
某些处理器允许未对齐的数据(可能以较低的速度),
有些人不允许这样做.

对于64位Intel架构,要求列于
Data Alignment when Migrating to 64-Bit Intel? Architecture:

The 64-bit environment,however,imposes more-stringent requirements on data items. Misaligned objects cause program exceptions.
[…]

  • Align 8-bit data at any address
  • Align 16-bit data to be contained within an aligned four-byte word
  • Align 32-bit data so that its base address is a multiple of four
  • Align 64-bit data so that its base address is a multiple of eight
  • Align 80-bit data so that its base address is a multiple of sixteen
  • Align 128-bit data so that its base address is a multiple of sixteen

因此,对齐不一定等于“字大小”,它可以是
少或多或少. Float80对应“扩展精度”
x86处理器的浮点类型,它的对齐方式是
要求是16个字节.

像C struct这样的复合类型在内存中布局
每个成员都在其自然边界(并插入填充
在必要时间.结构的对齐方式
本身是每个成员的最大对齐方式.

Swift Struct的内存布局没有正式记录(据我所知),但它可能类似于C结构.
这是一个简单的例子:

struct AStruct {
    var a = Int32(0)
    var b = Int8(0)
    var c = Int16(0)
    var d = Int8(0)
}
println(sizeof(AStruct))     // 9
println(alignof(AStruct))    // 4
println(strideof(AStruct))   // 12

内存布局(可能)是(* =填充):

aaaab*ccd

这里的对齐是4,因为这是Int32所需的对齐方式.结构占用9个字节,但“步幅”为12:
这保证了在结构数组中所有元素都满足
相同的路线.

(注意,Swift strideOf()对应于C的sizeof()函数,这在https://devforums.apple.com/message/1086107#1086107中有解释.)

Swift字符串的声明显示为

struct String {
    init()
}

但我们凡人都看不到实际的成员.
在调试器中它看起来像这样:

表示其成员是指针,无符号字和另一个指针.所有这些类型都有一个大小和在64位上对齐8个字节.这可以解释大小(24字节)和Swift的对齐(8个字节).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读