鲲鹏gcc mcmodel 选项详解

举报
卜乐 发表于 2021/05/29 17:47:55 2021/05/29
【摘要】 本文将向大家详细介绍mcmodel选项的作用以及鲲鹏gcc 在mcmodel选项上做的新功能支持。

本文将向大家详细介绍mcmodel选项的作用以及鲲鹏gcc 在mcmodel选项上做的新功能支持。

编译的过程中,编译器是不知道要操作的数据在哪里的,计算数据的地址的工作是在链接阶段实现的。也就是说,编译器需要先把拿取数据的汇编指令定下来,在编译结束之后,链接器进行重定位计算时再填上指令的操作数是多少。那么就有一个问题,编译器如何选择一个合适的指令拿取数据?

比如说在aarch64后端如果待链接符号的距离超过4GB(如图1),编译的时候又决定使用ADRP指令 (32bit寻址范围,如图2)。此时如果使用这种方式去链接,则会报relocation truncated to fit这样的错(如图3)。
image.png

图1:符号相对于.bss段的偏移大于4GB

image.png

图2:令集中对于ADRP指令的描述,可见其寻址范围只在正负4GB

image.png

图3:CESM代码中出问题的字段描述,R_AARCH64_ ADR_PREL_PG_HI21对应ADRP指令进行相对PC寻址

那么怎么解决这个问题?似乎也很简单,换个位宽大一些的指令不就可以了。

mcmodel选项就是做这个事情的。这个选项的本意是告诉编译器,你可以假设我的代码里面所有的符号的位置都在某个位宽的范围之内。比如-mcmodel=small,就是假设所有符号都在4GB范围内,32个bit的位宽就可以寻到符号的位置,那我们就用ADRP指令就可以了。

但是假设不成立的时候,比如上面的情况,ADRP指令就不行了,需要用位宽更大的指令。这个时候就需要增大mcmodel的预设,使用mcmodel=large,变更寻址方式为LDR指令。LDR指令只能绝对寻址,但是有更大的寻址范围。所以如果你的应用可以非地址无关编译的话,那么mcmodel=large理论上可以解决所有的问题。

而例如HPC 场景中的CESM应用需要在符号超过4GB寻址范围的时候,依然需要保持PC寻址(-fPIC地址无关功能)功能,这时候LDR指令就不管用了。
image.png

图4:aarch64 -mcmodle=large时的寻址方式

这是aarch64独有的一类问题。在x86上面,由于有可以大位宽的mov指令,它可以实现4GB以上的地址无关寻址。根据与x86后端对比可以发现,x86后端在mcmodel=medium的时候之所以还可以生成地址无关代码,主要原因是其寻址方式还是相对PC寻址。与mcmodel=small相比唯一的变动是相对寻址的指令由mov变成了movabs,可以进行更大范围的寻址(64bit)。
image.png

图5:x86 ABI 中对于mcmodle=medium、large的描述

反观aarch64后端,其实相对PC寻址的指令和64bit的加法指令都是有的,甚至是64位的相对PC寻址方式在ABI中都是有的(如图6)缺少的是这种重定位方式。
image.png

图6: Aarch64 ABI 中关于64位相对PC寻址的描述

鲲鹏GCC根据这个问题的痛点,新开发了-mcmodel=medium 和 -mlarge-data-threshold= 两个选项。通过软件模拟的方式,使用多条指令去模拟movabs指令,使得在HPC领域一些需要大范围地址无关寻址的应用能够平滑地从其他平台迁移到鲲鹏平台中来。感兴趣的朋友可以去open欧拉下载鲲鹏GCC的工具链尝试使用。

时间问题暂时写到此处,后续会继续更新一些鲲鹏gcc或者毕昇编译器相关优化选项的介绍,感兴趣的朋友敬请留言。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。