硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5786|回复: 8
收起左侧

[有问必答] 关于内存字节对齐问题

[复制链接]

34

主题

83

回帖

185

积分

初级会员

积分
185
发表于 2016-12-16 20:22:55 | 显示全部楼层 |阅读模式
  32位的CPU在正常情况下我们为了让其能在数据存储时得到更合理的运行效率我们会对内存4字节对齐,当使用外部SRAM或SDRAM16位数据总线时4字节对齐还有意义吗?是不是2字节对齐就可以了?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2016-12-17 09:40:43 | 显示全部楼层
CM内核支持非对齐访问,效率都是一样的,详情可以学习在权威指南。
回复

使用道具 举报

34

主题

83

回帖

185

积分

初级会员

积分
185
 楼主| 发表于 2016-12-17 10:31:39 | 显示全部楼层

回 eric2013 的帖子

eric2013:CM内核支持非对齐访问,效率都是一样的,详情可以学习在权威指南。 (2016-12-17 09:40) 
我想问的是当使用外部16位SDRAM时,4字节对齐是不是没有意义了?2字节对齐正好符合16位SDRAM存储特性。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2016-12-17 10:47:59 | 显示全部楼层

回 shuaigew88 的帖子

shuaigew88:我想问的是当使用外部16位SDRAM时,4字节对齐是不是没有意义了?2字节对齐正好符合16位SDRAM存储特性。 (2016-12-17 10:31) 
没有关系,都一样的,没什么区别。支持字节,半字和字访问。对齐不对齐没有任何关系。
回复

使用道具 举报

34

主题

83

回帖

185

积分

初级会员

积分
185
 楼主| 发表于 2016-12-17 11:26:06 | 显示全部楼层

回 eric2013 的帖子

eric2013:没有关系,都一样的,没什么区别。支持字节,半字和字访问。对齐不对齐没有任何关系。 (2016-12-17 10:47) 
使用外部SDRAM16位数据接口时如果定义的变量正好不是2字节对齐数据访问会损失效率吧?

比如字节对齐使用外部RAM地址从0x68000000开始:

struct _mem
{
   char a;      //1个字节,占用外部RAM的0X68000000低8位
   char b;      //1个字节,占用外部RAM的0X68000000高8位
  
   char c;           //1个字节,占用外部RAM的0X68000001低8位
   short buf[100]; //因为不是16位对齐,buf[0]的低8字节会分配0X68000001高8位存储,buf[0]的高8字节会分配0X68000002低8位存储,后面的元素存储结构以此类推,那么一个short就会访问两次存储器,如果设置内存2字节对齐就不会出现这样的问题是吧?麻烦讲解一下。
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2016-12-17 11:33:44 | 显示全部楼层

回 shuaigew88 的帖子

shuaigew88:使用外部SDRAM16位数据接口时如果定义的变量正好不是2字节对齐数据访问会损失效率吧?

比如字节对齐使用外部RAM地址从0x68000000开始:

....... (2016-12-17 11:26)
你的理解有误,一个地址仅对应一个字节。
0X68000000  是一个字节
0X68000001  是一个字节

跟你操作内部SRAM一样的。

总线接口支持字,半子和字节访问的。具体如何处理就是他硬件的处理方式了。为了方便观察结构变量成员的地址,你可以调试状态在mdk里面调用watch组件看即可,一目了然。
SRAM和SDRAM还不像NOR Flash,他们有专门的字节选择引脚。
回复

使用道具 举报

34

主题

83

回帖

185

积分

初级会员

积分
185
 楼主| 发表于 2016-12-17 11:56:32 | 显示全部楼层

回 eric2013 的帖子

eric2013:你的理解有误,一个地址仅对应一个字节。
0X68000000  是一个字节
0X68000001  是一个字节

....... (2016-12-17 11:33) 
嗯是的,可能是我表达的意思不够清楚,0X68000000、0X68000001是逻辑地址的两个字节比如正好对应16位总线的一次读写地址,在如:

byte C; //地址是0X68000002,如果是字节对齐,以上3个地址应该只占用物理存储的3个字节,如果是2字节对齐的话上面的3个字节变量应该是占用物理地址6个字节没错吧?

先假设我上面说的是正确的,那么内存分配很可能会这样
当字节对齐时BYTE A,B,C,地址分别是0X68000000、0X68000001、0X68000002,实际占用物理内存时的物理地址A和B被分配在物理地址0的高字节和低字节,C被分配在物理地址1的低字节(因为是16位数据总线,支持高低字节存储访问),这样只占用了物理地址的3个字节

如果是2字节对齐,这个时候逻辑地址与物理地址的数据总线存储特性一致,
BYTE A、B、C分别被分配到物理地址0、1、2,这样实际是占用了6个字节存储空间

在假设我上面的分析是正确的,如下:

字节对齐时:
BYTE A,B,C;   //分别按照物理地址高低字节存储(A和B占用物理地址0、C占用物理地址1的低8位)
UINT16  D;  //因为D是双字节变量,就会被拆开分别分配到物理地址1的高字节和物理地址2的低字节,这样访问变量D时处理器需要访问两次外部存储器?

如果是双字节对齐就不会出现以上问题,同时定义UINT32 E;//双字节对齐同样是访问两次,如果按照上面的结构就会访问3次。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2016-12-17 12:17:24 | 显示全部楼层
理解还是有偏差
“BYTE A、B、C分别被分配到物理地址0、1、2,这样实际是占用了6个字节存储空间”

是占用3个字节,具体自己再研究研究吧。还是没有理解透,暂时讨论这么多吧。
回复

使用道具 举报

34

主题

83

回帖

185

积分

初级会员

积分
185
 楼主| 发表于 2016-12-17 12:24:21 | 显示全部楼层

回 eric2013 的帖子

eric2013:理解还是有偏差
“BYTE A、B、C分别被分配到物理地址0、1、2,这样实际是占用了6个字节存储空间”

是占用3个字节,具体自己再研究研究吧。还是没有理解透,暂时讨论这么多吧。

....... (2016-12-17 12:17) 
好吧好吧,谢谢回答。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-16 13:49 , Processed in 0.041996 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表