添加__section__属性后部分全局数组未分配至指定.axpudata段的原因
问题:全局变量段属性失效的原因与场景分析
我给几个全局数据(函数外部定义,默认属于数据段)添加了指定段属性,代码如下:
char __attribute__(( aligned(256), __section__(".axpudata") )) mem_local [N_AXEMIS_PER_AXPU][LOCAL_SEGMENT_SIZE]; char __attribute__(( aligned(256), __section__(".axpudata") )) mem_private[N_AXEMIS_PER_AXPU][N_AXEC_PER_AXEMIS*N_THREAD_PER_AXEC][PRIVATE_SEGMENT_SIZE]; uint64_t __attribute__(( aligned(256), __section__(".axpudata") )) mem_knlargs[KNLARGS_SEGMENT_SIZE/8]; struct __attribute__(( aligned(256), __section__(".axpudata") )) es_t axpu_es [N_AXEMIS_PER_AXPU]; struct __attribute__(( aligned(256), __section__(".axpudata") )) reg_csr_t axpu_regs [N_AXEMIS_PER_AXPU];
查看映射文件时发现,mem_local、mem_private、mem_knlargs都被分配到.axpudata段,但axpu_es和axpu_regs却跑到了.bss段。虽然后者不影响功能,但想知道这个现象的成因,以及哪些场景会出现这类问题。
链接脚本相关配置如下:
.axpudata : { . = ALIGN(65536); *(.axpudata) } /* Uninitialized data */ . = ALIGN(0x10000); .bss : { __bss_start = .; __bss_start__ = .; *(.bss*) __bss_end = .; __bss_end__ = .; }
原因分析
问题核心是**__attribute__的放置位置错误**:你把属性写在了struct关键字和类型名es_t/reg_csr_t之间,这相当于给结构体类型本身添加属性,而非全局变量axpu_es/axpu_regs。
对于char、uint64_t这类基本类型,属性紧跟类型后会直接作用于变量,所以段属性能正常生效;但结构体类型的属性只会影响该类型的内存对齐特性,无法改变变量的段分配规则——未初始化的全局结构体变量依然会被编译器默认放到.bss段。
正确写法
需要把__attribute__放在变量名之前,也就是结构体类型声明之后:
struct es_t __attribute__(( aligned(256), __section__(".axpudata") )) axpu_es[N_AXEMIS_PER_AXPU]; struct reg_csr_t __attribute__(( aligned(256), __section__(".axpudata") )) axpu_regs[N_AXEMIS_PER_AXPU];
易出现此类问题的场景
- 定义结构体类型的全局变量时,误将属性应用到类型而非变量本身
- 使用
typedef定义结构体类型时,属性位置混淆(比如typedef struct { ... } __attribute__(...) my_struct_t;,此时属性作用于类型,而非后续定义的变量) - 混合使用类型属性和变量属性时,未明确区分两者的作用对象
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

