博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于对齐的一些问题探讨
阅读量:4205 次
发布时间:2019-05-26

本文共 1414 字,大约阅读时间需要 4 分钟。

无论是自己写代码,还是阅读一些开源的代码,总会遇到一些对齐问题,经过查阅资料和自己编程做的一些小实验,总结下关于对齐的那些事。

我个人把对齐分为字节对齐和页对齐,下面依次讨论

1.字节对齐

首先我们来思考一下CPU是如何读取数据的。

先明确一个问题,CPU不是按照字节来处理数据的,而是按照字长来处理数据的。所谓字长,就是CPU可以一次性读取的数据长度。假设CPU是32位的,那么CPU一次性就可以读取32位的数据。按照CPU的设计,读取的地址总是32的倍数开始。

字节对齐问题和CPU架构以及编译器有极大的关系。比如在x86架构中,即便是字节没有对齐,也不会出现问题,原因是x86架构的CPU支持读取奇数位地址,但是会降低程序运行的效率。用gcc编译的程序,编译器会默认4字节对齐。如果定义了一个自己没有对齐的结构体,编译器会自动帮你对齐。

但是如果是某些不支持读取奇数地址的CPU架构中,就会产生意想不到的问题。

1.1字节不对齐可能会产生错误

让我们来考察这么以下代码。

struct A{    short i;    short j:1;};struct B{    short i;};struct A a;struct B b;

如果是某些架构的CPU中,b的起始地址就会是奇数,当读取b的内容就有可能会从a.j开始读取。

当然,现在这种架构的CPU往往只会在嵌入式行业中有所应用,但是考虑到代码的可移植性,字节对齐还是很有必要做的。

1.2字节不对齐会对降低程序运行效率

考察一下结构体

struct A{    short  i;    int    j;    short  k;};struct B{    short  i;    short  k;    int    j;};struct A a;struct B b;

读取a和b所用的时间是相同的吗?

答案是不相同。读取a需要CPU读取三次内存,b只需要读取两次内存就可以。如果程序中存在着大量的字节不对齐的结构体,会造成程序运行效率的下降。

2.页面对齐

页面对齐对做普通应用开发的程序员来说,是不需要操心的,但是如果涉及到高性能程序开发,比如数据转发,就需要对页面对齐有所了解。

2.1虚拟内存和内存页

关于这个问题,需要去参考计算机组成原理相关的书籍或者网上查找一些资料,这里需要知道,当CPU触发了缺页流程,是很浪费CPU性能的。这也是为什么dpdk等高性能IO开发组件需要用到巨页的原因。如果页面没有对齐,容易造成缺页。比如以下场景:

一段小于一个页面大小的连续内存,当我们需要访问这段内存的时候,CPU就需要读取两个页面,无疑增加了缺页的概率。当然,如果我们用内核的malloc函数,如果申请的内存小于一个页面大小,系统是不会给我们分配跨页的内存,但是如果我们需要开发一套内存管理程序,就需要考虑这个问题。当上层业务申请内存的时候,不能简单的返回申请内存的起始地址,而应该先判断是否跨页。

2.2如何进行页对齐

参考内核代码

向下对齐:#define alignment_down(a, size) (a & (~ (size-1)) )

向上对齐:#define alignment_up(a, size)   ((a+size-1) & (~ (size-1)))

size为页大小,这个宏要求size为2的n次幂大小,否则计算会出错

转载地址:http://dyali.baihongyu.com/

你可能感兴趣的文章
springMVC 中的restful 架构风格
查看>>
《剑指offer》第六十题(n个骰子的点数)
查看>>
Mac Eclipse+Maven+TestNg+ReportNg 生成测试报告
查看>>
c语言求平面上2个坐标点的直线距离、求俩坐标直线距离作为半径的圆的面积、递归、菲波那次数列、explode...
查看>>
Jsoup进阶选择器
查看>>
初识servlet
查看>>
Streams实践之表空间级复制
查看>>
Streams实践之Schemas级复制
查看>>
as, idea 出现 Gradle's dependency cache may be corrupt 错误分析
查看>>
部分习题题解:
查看>>
第一次作业
查看>>
20169220 <网络攻防实践> 第二周学习总结
查看>>
数字工具类
查看>>
jade
查看>>
Redis Cluster高可用集群在线迁移操作记录
查看>>
检索策略的概念
查看>>
流行视频格式讲解 分类: 文件格式 2013-...
查看>>
离散化
查看>>
/tmp/orbit-oracle/目录inode耗尽
查看>>
IdentityServer4服务器配置
查看>>