ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

内存对齐 --12.12 学习笔记

2020-12-12 18:31:12  阅读:337  来源: 互联网

标签:-- 内存 packing 12.12 pragma 对齐 alignment pack


我们知道内存的最小单元是一个字节,当cpu从内存中读取数据的时候,是一个一个字节读取,所以内存对我们应该是入下图这样:

 

                                                                                           

但是实际上cpu将内存当成多个块,每次从内存中读取一个块,这个块的大小可能是2、4、8、16等,

那么下面,我们来分析下非内存对齐和内存对齐的优缺点在哪?

内存对齐是操作系统为了提高访问内存的策略。操作系统在访问内存的时候,每次读取一定长度(这个长度是操作系统默认的对齐数,或者默认对齐数的整数倍)。如果没有对齐,为了访问一个变量可能产生二次访问。

至此大家应该能够简单明白,为什么要简单内存对齐?

  1. 提高存取数据的速度。比如有的平台每次都是从偶地址处读取数据,对于一个int型的变量,若从偶地址单元处存放,则只需一个读取周期即可读取该变量;但是若从奇地址单元处存放,则需要2个读取周期读取该变量。
  2. 某些平台只能在特定的地址处访问特定类型的数据,否则抛出硬件异常给操作系统。

如何内存对齐

  1. 对于标准数据类型,它的地址只要是它的长度的整数倍。
  2. 对于非标准数据类型,比如结构体,要遵循一下对齐原则:

 

1. 数组成员对齐规则。第一个数组成员应该放在offset为0的地方,以后每个数组成员应该放在offset为min(当前成员的大小,#pargama pack(n))整数倍的地方开始(比如int在32位机器为4字节,#pargama pack(2),那么从2的倍数地方开始存储)。

2. 结构体总的大小,也就是sizeof的结果,必须是min(结构体内部最大成员,#pargama pack(n))的整数倍,不足要补齐。

3. 结构体做为成员的对齐规则。如果一个结构体B里嵌套另一个结构体A,还是以最大成员类型的大小对齐,但是结构体A的起点为A内部最大成员的整数倍的地方。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。

 

手动设置对齐模数:

    1. #pragma pack(show)

显示当前packing alignment的字节数,以warning message的形式被显示。

    1. #pragma pack(push)

将当前指定的packing alignment数组进行压栈操作,这里的栈是the internal compiler stack,同事设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment数组压栈。

    1. #pragma pack(pop)

从internal compiler stack中删除最顶端的reaord; 如果没有指定n,则当前栈顶record即为新的packing alignement数值;如果指定了n,则n成为新的packing alignment值

    1. #pragma pack(n)

指定packing的数值,以字节为单位,缺省数值是8,合法的数值分别是1,2,4,8,16。

 下面是我个人的一些代码段  ,不懂的可以加我微信或者直接再CSDN上练习我哦

 

 

 

#include <stdio.h>
#include <stdlib.h> 
					//本机的对齐模数是8  其他电脑可能不同,输出结果可能有误!!
					 
/* 	#pragma pack(show)   显示当前packing alignment的字节数,以warning message的形式被显示*/
/* 	#pragma pack(push) 将当前指定的packing alignment数组进行压栈操作,这里的栈是the internal 
compiler stack,同事设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment
数组压栈。*/
/* 	#pragma pack(pop) 从internal compiler stack中删除最顶端的reaord; 如果没有指定n,则当前栈顶
record即为新的packing alignement数值;如果指定了n,则n成为新的packing alignment值*/

typedef struct 
{
	int a; // 0-3
	char b; // 4-7 
	double c;  //8-15
	float d; 	// 20
} Student ;   

Student stu1 ; 
#pragma pack(1)  // 修改现在的内存模数 
typedef struct 
{
	int a; // 0-3
	char b; // 4-7 
	double c;  //8-15
	float d; 	// 20
} Student1 ; 

Student1 stu2 ; 
void text01()    // 测试内存对齐 
{
	printf("%d\n",sizeof stu1);  // 算出来的sizeof实际上是24  为何呢?  内存对齐与对齐模数
	/*所以Student内部对齐之后的大小为20 ,整体对齐,整体为最大类
	型的整数倍 也就是8的整数倍 为24*/
	printf("%d\n",sizeof stu2); 
	
 }
 
#pragma pack(8)
typedef struct 
{
	int a; // 0-3
	Student stuT; 
	double b ;
} Student2 ; 
 
Student2 stu3 ; 
void text02()
{
	printf("%d\n",sizeof stu3);
}
int main(void)
{
	//text01();
	text02();
}

 

标签:--,内存,packing,12.12,pragma,对齐,alignment,pack
来源: https://blog.csdn.net/qq_50510142/article/details/111082260

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有