4

我正在尝试了解机器代码对齐的原理。我有一个可以在运行时生成机器代码的汇编器实现。我在每个分支目标上使用 16 字节对齐,但看起来这不是最佳选择,因为我注意到如果我删除对齐,有时相同的代码会运行得更快。我认为这与缓存线宽度有关,因此某些命令被缓存线切断,因此 CPU 会遇到停顿。因此,如果在一个地方插入了一些对齐字节,它会将指令移动到某个地方,进一步通过缓存边界线......

我希望实现一个自动对齐程序,它可以将代码作为一个整体处理并根据CPU的规范(缓存线宽,32/64位等)插入对齐...

有人可以提供有关此程序的一些提示吗?例如,目标 CPU 可以是 Intel Core i7 CPU 64 位平台。

谢谢你。

4

4 回答 4

3

我没有资格回答你的问题,因为这是一个如此庞大而复杂的话题。除了高速缓存行大小之外,这里可能还有更多机制在起作用。

但是,我想向您指出Agner Fog 的站点以及您可以在那里找到的编译器制造商的优化手册。它们包含有关此类主题的大量信息 - 缓存行、分支预测和数据/代码对齐。

于 2011-03-07T12:00:57.410 回答
2

段落(16 字节)对齐通常是最好的。但是,它可以强制一些“本地”JMP 指令不再是本地的(由于代码大小膨胀)。也可能导致没有那么多代码被缓存。我只会对齐主要的代码段,不会对齐每个微小的子例程/JMP 部分。

于 2011-03-07T14:24:17.213 回答
1

但是,不是专家……指向不会在指令缓存中的位置的分支应该从对齐中受益最大,因为您将读取整个指令缓存行来填充管道。鉴于该声明,前向分支将在函数的第一次运行时受益。向后分支(例如“for”和“while”循环)可能不会受益,因为分支目标和后续指令已经被读入缓存。请按照马丁斯答案中的链接进行操作。

于 2011-03-07T12:43:02.950 回答
1

如前所述,这是一个非常复杂的领域。Agner Fog 似乎是一个值得游览的好地方。至于复杂性,我在这里遇到了Torbjörn Granlund关于“通过不变整数改进除法”的文章以及他用来说明他的新算法的代码中的第一条指令 - 我猜 - 主要标签是 nop - 没有操作。根据评论,它显着提高了性能。去搞清楚。

于 2011-03-08T18:12:15.083 回答