zoukankan      html  css  js  c++  java
  • c++内存对齐

    内存对齐的原因

    为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。因为为了访问未对齐的内存,CPU需要作两次内存访问。然而,对齐的内存访问仅需要一次访问。

    内存对齐的规则

    1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照 #pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

    2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较大的那个进行。

    普通结构体

    一般c++编译器默认的内存的对齐值为8个字节。对于下面的TEST结构体。因为其第一个字段为char所占字节为1,而第二个字段为int在32位系统中占4个字节,默认对齐值为8,宏观对齐值为4。因为char cNum1的字节大小为1地址为0x00AFFC50,所以其对齐值为1。int cNum2占4个字节所以对齐值为4,所以其首地址要能被4整除所以0x00AFFC51-0x00AFFC53用0xCC填充用来对齐。结构体总体大小为实际宏观对齐值与默认对齐值中较大的那个,所以sizeof(TEST)的大小为0x8.

    结构体中含有数组

    如果结构体宏含有数组则用数组的类型参与对齐值的计算,不能按数组的总大小参与对齐值的运算。

    结构体中含有结构体

    如果结构体中含有结构体则应用结构体的对齐值参与对齐值的运算,而不能用结构体的大小参与对齐值的运算。

    内存没对齐进行错位访问数据

    DWORD * pDword = new DWORD[10]();
    pDword = (DWORD*)((BYTE*)pDword + 1);
    
    DWORD a = *pDword;				//进行了错位访问数据
    

    x86CPU的EFLAGS寄存器的AC标志位是对齐检查标志位,其默认是为0的,这时cpu进行错位访问数据(访问未对齐的数据)时需要CPU多执行一些操作,比访问对齐的数据效率要低但是并不会产生异常。如果AC标志位为1则一旦CPU进行错位访问时就会产生一个异常,但是对于x86-64处理器来说,CPU会默认处理这种错误。但是对于IA-64处理器来说其CPU不能处理这种错误会将这种错误传递给操作系统,Windows操作系统会产生EXCEPTION_DATATYPE_MISALINGNMENT异常。

    处理IA-64处理器上错位访问数据

    让操作系统处理

    SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);
    

    通过调用在进程中调用SetErrorMode并传入参数SEM_NOALIGNMENTFAULTEXCEPT来让操作系统修正此进程中所有的错位数据的访问,一旦改变该标志就无法在进程生命周期再次改变它,且这样进程可能会遇到严重的性能下降。

    让编译器处理

    Microsoft Visual C/C++编译器利用__unaligned关键字修饰可能会错位访问数据的指针,从而生成额外的指令来访问数据。

    DWORD * pDword = new DWORD[10]();
    pDword = (DWORD*)((BYTE*)pDword + 1);
    
    DWORD a = *(__unaligned DWORD *)pDword;				//使用__unaligned关键字访问数据
    

    参考《Windows核心编程》

  • 相关阅读:
    iOS UITableViewCell中包含UICollectionView嵌套 解决UITableViewCell显示异常
    mac 终端创建podfile文件
    iOS UIScrollView弹性问题
    NSMutableParagraphStyle与NSParagraphStyle的使用
    iOS 单个控制器隐藏 导航栏下划线
    iOS UICollectionView reloadData后立即获取contentSize.height高度
    高德地图API开发二三事(一)如何判断点是否在折线上及引申思考
    Python-6
    Python-模块
    python-递归函数和内置函数笔记汇总
  • 原文地址:https://www.cnblogs.com/revercc/p/13810678.html
Copyright © 2011-2022 走看看