zoukankan      html  css  js  c++  java
  • 内存对齐全攻略—刀枪入库 功德圆满

    推荐阅读顺序,希望给你带来收获~

    内存对齐全攻略--不涉及位域的内存对齐原则

    内存对齐全攻略--涉及位域的内存对齐原则

    内存对齐全攻略—刀枪入库 功德圆满

    全攻略有点大放厥词,哗众取宠了,其实是一些常见的问题罢了。但是自认为总结的还算全面一点吧,请大家多多赐教,我只是个初学者。

    接下来主要讨论四点:
    一、不涉及位域的内存对齐
    二、涉及位域的内存对齐
    三、成员变量含有结构体的内存对齐情况
    四、要求内存对齐的原因及优点

    ---------------------------------------------------------------------------------------------------

    这次三、四点一次说了,关于内存对齐全攻略的问题,就算刀枪入库,功德圆满了,呵呵,各回各家,各找各妈~~

    ---------------------------------------------------------------------------------------------------

    三、成员变量含有结构体的内存对齐情况

          成员变量含有结构体的内存对齐规则:

    1)   内存对齐全攻略--不涉及位域的内存对齐原则  这篇文章中的三条

    2)   结构体中作为成员变量的结构体的”对齐模数”为该结构体变量中成员变量的sizeof最大值,即:

      Struct temp{int t;char c;…}

      Struct a{temp t; }

      则在a中temp的对齐模数为MAX(sizeof(int),sizeof(char),…)

      举例说明,程序如下:

     1#include <iostream>
     2using namespace std;
     3
     4struct temp
     5{
     6    char c;
     7    int i;
     8};
     9struct A
    10{
    11    short s;
    12    temp t;
    13    char c;
    14};
    15void main()   
    16{   
    17    A a;
    18    a.s=1;
    19    a.t.c=2;
    20    a.t.i=3;
    21    a.c=4;
    22    printf("sizeof(A)=%d\n",sizeof(A));
    23}  

    过程如下:

    1、  在A a;处设断点,Go;

    2、  找到 a在内存空间中的地址为0012ff38,如下图:

    3、  查看现在0012ff38起始的内存空间存储情况:

    4、  单步调试如下图(反汇编代码+内存空间分配+我的注释+我的疑问):

    5、到此,有关内存对齐的规则什么的就冇(河南方言 读māo)了,接下来说一下,说一内存对齐的原因和优点

    四、内存对齐的原因和优点(真想写上,大家自己去搜搜看就行了…)

    搜索+翻译+理解有了以下的文字,参考文章:

    Data alignment: Straighten up and fly right

    需要内存对齐的原因:

    如果你不理解和处理软件中的对其问题,以下糟糕的情况在你的软件中将会越来严重:

    1)       软件运行速度越来越慢

    2)       应用程序被锁定

    3)       操作系统崩溃

    4)       软件会因错误的结果而逐渐被淘汰

    内存对齐的优点(也算是原因吧):

    1)       实现平台无关:不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

    2)       内存对齐以后,处理器的读取速度将会大大提高

    以下将主要对第二点坐下说明:

    为了阐明内存对齐背后的规则,我看一个常见的小问题,并且来看一下不同的内存读取粒度对这个问题有什么影响。这个问题很简单:

    1)       从地址0读取四个字节到处理器的寄存器

    2)       从地址1读取四个字节到处理器的寄存器

    首先我们来看一下当处理器的内存读取粒度为1时的情况:

     

    这符合天真的程序员所认为的内存工作的模式:从地址0和从地址1开始的四次内存访问是相同的。下面来看一下处理器的内存读取粒度为2时的情况:

     

    内存读取粒度为2时内存读取次数是粒度为1时次数的一半。而每次内存读取都需要固定数额的开销,所以尽量减少内存读取次数将会有效的帮助处理器提高性能。

             不过,请注意当从地址1开始读取时的情况。由于这个地址没有均匀的落在处理器的内存读取边界上,处理器就需要做一些额外的开销。这样的地址就被称为 未对齐地址(暂且这样翻译,我看到原文是斜体字,应该是专有名词,不知道是不是这样翻译的,如果不是的话,请留言或回复说一下,谢谢了~)。因为地址1是未对齐的,当存取粒度为2时,处理器就要做一次额外的内存读取操作,这样就会减低操作的效率。

             最后呢,我们来检测一下内存读取粒度为为4时的情况:

     

    可以看得出来,内存存取粒度为4的处理器能够快速的一次从对齐的地址中读取四个字节。而从为对齐的地址中却需要翻倍的次数。

    这里细说一下粒度为2从地址1开始的情况,此时,CPU先访问一次内存,读取0-1自己的数据进寄存器,并再次读取2-3字节的数据进寄存器,接着把字节0和字节3的数据剔除,合并1,2字节的数据进寄存器。呵呵,对一个未对其的数据进行这么多额外的操作,你用电脑时,不急死才怪呢~~

    《完》

    感谢博客园,感谢支持我的朋友,是你们让我有了写下去的愿望和勇气!

  • 相关阅读:
    sql server 高可用日志传送
    sql server 高可用性技术总结
    sql server 分区(上)
    X86逆向10:学会使用硬件断点
    从零开始学 Web 之 jQuery(三)元素操作,链式编程,动画方法
    PIE SDK打开自定义栅格数据
    PIE SDK打开网络地图数据
    PIE SDK打开长时间序列数据
    Leetcode 75.颜色分类 By Python
    Leetcode 80.删除排序数组中的重复项 II By Python
  • 原文地址:https://www.cnblogs.com/shitouer/p/1707686.html
Copyright © 2011-2022 走看看