免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2975 | 回复: 9
打印 上一主题 下一主题

内存对齐的概念. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-09 12:32 |只看该作者 |倒序浏览
内存对齐比较精确的定义:一个数据类型只允许存放在该数据类型整数倍的内存位置上;内存对齐通常是一些硬件系统的硬性要求;

          例子:
#include <stdio.h>;

int main(void)
{
        char    *str = NULL;
        short int       *test1 = NULL;
        int             *test2 = NULL;

        str = (char *)malloc(100);
        if(str == NULL){
                printf("malloc error\n";
                exit(1);
        }

        printf("the str addr is %x\n", str);
        printf("the str+2 addr is %x\n", str+2);

        test1 = (short int *)(str + 2);
        *test1 = 1;

        printf("step1 pass\n";

        test2 = (int *)(str + 2);
        *test2 = 1;

        printf("step2 pass\n";

        return  0;
}

在sparc上运行结果为:
the str addr is 20ca0
the str+2 addr is 20ca2
step1 pass
总线错误 (core dumped)

而在intel上运行没有任何问题;

上述程序,*test1是short int型,长度是2字节,它所放的内存位置str+2是2的整数倍,没问题;而*test2是int型,长度是4字节,它所放的内存位置str+2不是4的整数倍,因此会总线错误 (core dumped)

因此可以看出,在sparc上有内存对齐的要求,大家编程时要注意这一点!

不对请更正!

论坛徽章:
0
2 [报告]
发表于 2003-07-09 17:14 |只看该作者

内存对齐的概念.

我觉得这样理解可能不正确

因为对齐只是编译器为了内存访问性能更高所做的优化
另外你也可以选择不对齐
有对应编译选项

可以看顶上FAQ查找pcak说明

在网络包中pack(1)更是重要
因为不同的CPU体系结构不一样

另外每个平台编译器优化对齐数也不一样
所以在这种时候一般会使用pack(1)对齐

论坛徽章:
0
3 [报告]
发表于 2003-07-10 08:29 |只看该作者

内存对齐的概念.

楼上,不知道你在sparc上运行过上述程序没有,保证你出core;

另外,编译器对齐确实可以提供内存访问速度,但是这里的编译器对齐只是针对struct,而对于c语言里的原始类型,如 int,short int等必须放在该数据类型整数倍的位置上,如果不这样做,你的程序就会core掉;

论坛徽章:
0
4 [报告]
发表于 2003-07-10 09:50 |只看该作者

内存对齐的概念.

某些RISC对此有硬性要求,不只是数据,指令代码都要求。对CISC以及其他RISC,大多是为了提升性能。

论坛徽章:
0
5 [报告]
发表于 2003-07-10 12:16 |只看该作者

内存对齐的概念.

那如果一个struct

struct{
char a;
int b;
char c;
int d;
}
使用pack(1)后访问的话呢  
使用pack(1)后它们都是连接保存的

我没有solaris条件

但是在网络包中对结构都使用pack(1) 收发
所以觉得这不是问题

同样那个程序也没有办法测试
如果有条件的话可以知道是什么问题的

论坛徽章:
0
6 [报告]
发表于 2003-07-10 13:57 |只看该作者

内存对齐的概念.

在某些系统上,如sparc,你的结构在访问int b时可能就会core。不过这个问题也与编译器的处理有关,有些编译器会对非对齐的数据特殊处理,保证不产生core。
至于网络包发送,因为面对的都是字节,没有对结构成员的访问,所以不存在问题。此外,结构直接传送是不鼓励的,会有不兼容的问题出现,包括字长、字节序等,即使你用了pack(1)也是不行的。所以,在网络编程时没有必要用pack(1)。
习惯了C编程的程序员总是希望不用进行编解码就可以很好地进行网络通信,其实完全是不对的。不要对对端做太多假设,这样你的应用才有更好的可移植性。相对与网络传输的性能而言,编解码的开销根本不算什么。

论坛徽章:
0
7 [报告]
发表于 2003-07-10 14:08 |只看该作者

内存对齐的概念.

原帖由 "无双" 发表:
那如果一个struct

struct{
char a;
int b;
char c;
int d;
}
使用pack(1)后访问的话呢  
使用pack(1)后它们都是连接保存的

我没有solaris条件

但是在网络包中对结构都使用pack(1) 收发
所以觉得这?.........
   

无双,你知道你的这个结构体在用pack(1)后,在访问结构体成员b时,它是要访问两次的,然后把这两次访问的结果和并起来,这样才是b成员的数据;

论坛徽章:
0
8 [报告]
发表于 2003-07-10 14:18 |只看该作者

内存对齐的概念.

原帖由 "fieryfox" 发表:
在某些系统上,如sparc,你的结构在访问int b时可能就会core。不过这个问题也与编译器的处理有关,有些编译器会对非对齐的数据特殊处理,保证不产生core。
至于网络包发送,因为面对的都是字节,没有对结构成员的访..........
   


对齐的原因不是节省带宽
我想在这点上你是理解错了

有的系统对结构使用不同的对齐方式如8字节对齐 并且还有大印第安小印弟安区别

所以如果在不同操作系统上发送的包
那么其它系统会不能理解你包的内容
因此需要对1位对齐

这点可以看顶上FAQ中讨论 里面有solaris linux windows平台上各编译器选项的讨论

还有就是传送的时间不访问
但收到的一方是访问的
直接访问那个结构 直接按1字节对齐的方式访问
所以在多数网络操作系统中 没有限制某个变量一定要从哪里开始保存
只是性能上有差异

论坛徽章:
0
9 [报告]
发表于 2003-07-10 15:28 |只看该作者

内存对齐的概念.

你的这些问题我前面的帖子里都说了,而且强调了即使pack(1)在异构网络环境中也是有问题的。我说编解码的开销相比网络传输的性能根本不算什么,并不是说带宽的问题,而是指你的应用的性能问题(增加编解码功能对网络应用的影响很小)。像你说的“大印第安小印弟安区别”(我的帖子里说的是字节序。目前的硬件体系还没有位序问题,这也是值得庆幸的),直接的结构传送是无法避免的,所以不能用结构传送,即使是pack(1)。
所以,系统的对齐方式对网络通信本来是不该有影响的,重要的仍然是字长、字节序这些问题。

论坛徽章:
0
10 [报告]
发表于 2003-07-10 19:14 |只看该作者

内存对齐的概念.

老大
那你先开发一个linux和windows通信的网络程序后再说

做和solaris的更好
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP