• 每日一问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博客

  • 相关阅读:
    HHUOJ 1321
    数据结构应用
    数据结构应用
    数据结构与算法分析
    数据结构与算法分析
    CSS -- 字体样式
    CSS -- 选择器
    CSS
    HTML -- 表单元素2
    HTML -- 表单元素1
  • 原文地址:https://www.cnblogs.com/honernan/p/14088507.html
Copyright © 2020-2023  润新知