zoukankan      html  css  js  c++  java
  • 每日一问8:C++中的内存对齐机制是什么

    每日一问8:C++中的内存对齐机制是什么

    什么是内存对齐

    ​ 要理解内存对齐我们先来看一个现象:

    #include<iostream>
    #include<Windows.h>
    #pragma pack (8)
    using namespace std;
    typedef struct {
    	char b;
    	double c;
    	int a;
    } A;
    typedef struct {
    	int a;
    	char b;
    	double c;
    } B ;
    int main() {
    	A a;
    	B b;
    	cout << "sizeof(a)=" << sizeof(a) << ends << "sizeof(b)=" << sizeof(b) << endl;
    	return 0;
    
    }
    

    运行结果如下:

    ​ 可以看到仅仅是调换了结构体中数据的顺序,结构的大小就变化了,这里就是内存对齐导致的一个结果。

    ​ 而较为正式的定义是:现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。

    为什么要内存对齐

    ​ 要理解为什么需要内存对齐,我们观察一下当没有内存对齐时的情况就可以知道。

    ​ 首先我们要知道内存存取粒度这个概念。计算机中,内存可以理解为一个字节数组,但大部分CPU都不是按字节来读取内存,一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,这些单位就称为内存存取粒度

    ​ 接下来我们来比较有无内存对齐的不同情况,任务是,先从地址0读取4个字节到寄存器,然后从地址1读取4个字节到寄存器。
    1.单字节存取


    ​ 单字节存取的情况下,对齐和不对齐都为四次操作。

    2.双字节存取

    ​ 双字节存取的情况下,从地址0读取四个字节只要两次,而从地址1读取需要三次。

    3.四字节存取

    ​ 四字节存取的情况下,从地址0读取四个字节只要一次,而从地址1读取需要两次。

    ​ 由上我们可以看到,内存对齐后,会提升程序的效率。

    1)可以访问未对齐的内存,但是会影响性能。例如x86架构的CPU

    2)抛出异常or静默访问错误的地址(内存对齐是为了方便移植

    总结:防止数据随意存放,cpu访问内存对齐的速度会大大提升。

    内存对齐是怎么运行的

    ​ 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。也可以使用#pragma pack ()来取消自定义字节对齐方式。

    对齐规则:
    1.基本类型的对齐值就是其sizeof值;

    2.struct,class,union类型的对齐量等于它的非静态成员变量中最大的对齐量。标准规定所有的对齐量必须是2的幂

    3.编译器可以通过#pragma pack指定的对齐参数,类型的实际对齐值是该类型的对齐值与指定的对齐参数的最小值。

    参考博客:

    1. 为什么要内存对齐 Data alignment: Straighten up and fly right_子虚-CSDN博客

    2.关于内存对齐_子虚-CSDN博客

  • 相关阅读:
    昆石VOS3000_2.1.4.0完整安装包及安装脚本
    KVPhone,VOS官方的SIP软电话电脑客户端
    昆石VOS2009 VOS3000无漏洞去后门电脑管理客户端大全
    2017年最新(4月20日)手机号码归属地数据库分享
    2017年最新VOS2009/VOS3000最新手机号段导入文件(手机归属地数据)
    Android:onNewIntent()
    三星S4使用体验(Markdown版)
    apple公司的潮起潮落——浪潮之巅
    microsoft的罗马帝国——浪潮之巅
    我的iOS开发之路
  • 原文地址:https://www.cnblogs.com/honernan/p/14088507.html
Copyright © 2011-2022 走看看