zoukankan      html  css  js  c++  java
  • 什么是内存?以及内存的编址方法和内存对齐

     什么是内存? (硬件和逻辑两个角度)
    从硬件角度:内存实际上是电脑的一个配件(一般叫内存条)。根据不同的硬件实现原理还可以把内存分成SRAM和DRAM (DRAM又有好多代,譬如最早的SDRAM,后来的DDR1、DDR2 ... .. LPDDR)
    从逻辑角度:内存是这样一种东西,它可以随机访问(随机访问的意思是只要给一一个地址,就可以访问这个内存地址)、并且可以读写(当然了逻辑上也可以限制其为只读或者只写) ;内存在编程中天然是用来存放变量的(就是因为有了内存,所以c语言才能定义变量,c语言中的一个变量实际就对应内存中的一个单元)

    内存的逻辑抽象图(内存的编程模型)
    从逻辑角度来进,内存实际上是由无限多个内存单元格组成的,每个单元格有一个固定的地址叫内存地址,这个内在地址和这个内存单元格唯一对应且永久绑定。

    以大楼来类比内存是最合适的。逻辑上的内存就好象是一栋无限大的大楼,内存的单元格就好象太楼虫的一个个小房间。每个内存单元格的地址就好象每个小房间的房间号。内存中存储的内容就好象住在房间虫的人一样。

    逻辑上来说,内存可以有无限大(因为数学上编号永远可以增加,无尽头)。但是现实中实际的内存大小是有限制的,譬如32位的系统(32位系统指的是32位数据线,但是一般地址线也是32位,这个地址线32位决定了内存地址只能有32位二进制,所以逻辑上的大小为2的32次方)内存限制就为4G(譬如我32位CPU装32位windows,但实际电脑只有512M内存)。
     

    内存位宽(硬件和逻辑两个角度)

    从硬件角度讲:硬件内存的实现本身是有宽度的,也就是说有些内存条就是8位的,而有些就是16位的。那么需要强调的是内存芯片之间是可以并联的,通过并联后即使8位的内存芯片也可以做出来16位或32位的硬件内存。

    从逻辑角度讲:内存位宽在逻辑上是任意的,甚至逻辑上存在内存位宽是24位的内存(但是实际上这种硬件是买不到的,也没有实际意义)。从逻辑角度来讲不管内存位宽是多少,我就直接操作即可,对我的操作不构成影响。但是因为你的操作不是纯逻辑而是需要硬件去执行的,所以不能为所欲为,所以我们实际的很多操作都是受限于硬件的特性的。譬如24位的内存逻辑上和32位的内存没有任何区别,但实际硬件都是32位的,都要按照32位硬件的特性和限制来干活。

    位和字节
    内存单元的大小单位有4个:位(1bit)   字节(8bit)   半字(一般是16bit)       字 (一般是32bit)
    在所有的计算机、所有的机器中(不管是32位系统还是16位系统还是以后的64位系统),位永远都是1bit,字节永远都是8bit。

    字和半字

    历史上曾经出现过16位系统、32位系统、64位系统三种,而且操作系统还有windows、linux、 ios等很多,所以很多的概念在历史上曾经被混乱的定义过。

    建议大家对字、半字、双字这些概念不要详细区分,只要知道这些单位具体有多少位是依赖于平台的。实际工作中在每种平台上先去搞清楚这个平台的定义(字是多少位,半字永远是字的一-半,双字永远是字的2倍大小),编程时一般根本用不到字这个概念,那我们区分这个概念主要是因为有些文档中会用到这些概念,如果不加区别可能会造成你对程序的误解。在linux+ARM这个软硬件平台上,字是32位的。

    内存编址方法

    内存在逻辑上就是一个一个的格子,这些格子可以用来装东西(里面装的东西就是内存中存储的数),每个格子有一个编号,这个编号就是内存地址,这个内存地址(一个数字)和这个格子的空间(实质是一个空间)是一一对应且永久绑定的。这就是内存的编址方法。

    在程序运行时,计算机中CPU实际只认识内存地址,而不关心这个地址所代表的空间在哪里,怎么分布这些实体问题。因为硬件设计保证了按照这个地址就一定能找到这个格子,所以说内存单元的2个概念:地址和空间是内存是内存单元的两个方面。

         关键:内存编址是以字节为单位的

    我随便给一个数字(譬如说7),然后说这个数字是一个内存地址,然后问你这个内存地址对应的空间多大?这个大小是固定式,就是一个字节(8bit)。
    如果把内存比喻位一栋大楼,那么这个楼里面的一个一个房间就是一个一个内存格子,这个格子的大小是固定的8bit,就好象这个大楼里面所有的房间户型是一样的。



    内存和数据类型的关系

    C语言中的基本数据类型有: char short int long float double

    整形(整数类型,这个整就体现在它和CPU本身的数据位宽是一样的)譬如32位的CPU,整形就是32位,int :就是32位。

    数据类型和内在的关系就在于,数据类型是用来定义变量的,而这些变量需要存储、运算在内存中所以数据类型必须和内存相匹配才能获得最好的性能,否则可能不工作或者效率低下。

    在32位系统中定义变量最好用int,因为这样效率高。原因就在于32位的系统本身配合内存等也是32位,这样的硬件配置天生适合定义32位的int类型变量,效率最高。也能定义8位的char类型变量或者16位的short类型变量,但是实际上访问效率不高。

    在很多32位环境下,我们实际定义bool类型变量(实际只需要1个bit就够了)都是用int来实现bool的。也就是说我们定义一个bool b1;时,编译器实际帮我们分配了32位的内存来存储这个bool变量b1。编译器这么做实际上浪费了31位的内存,但是好处是效率高。

    问题:实际编程时要以省内存为大还是要以运行效率为重?答案是不定的,看县体情况。很多年前内存很贵机器上内存都很少,那时候写代码以省内存为主。现在随着半导体技术的发展内存变得很便宜了,现在的机器都是高配,不在乎省一点内存,而效率和用户体验变成了关键。所以现在写程序大部分都是以效率为重。

    内存对齐

    我们在c中int a;定义一-个int类型变量,在内存中就必须分配4个字节来存储这个a。有这么2种不同内存分配思路和策略:

    (如图)第一种:0  1  2  3                          对齐访问

                第二种:1  2  3  4 或者 2  3  4  5 或者 3  4  5  6   非对齐访问

    内存的对齐访问不是逻辑的问题,是硬件的问题。从硬件角度来说,32位的内存它0123四个单元本身逻辑上就有相关性,这4个字节组合起来当作一个int硬件上就是合适的,效率就高。

    对齐访问很配合硬件,所以效率很高,非对齐访间因为和硬件本身不搭配,所以效率不高。... S因为兼容性的问题,一般硬件也都提供非对齐访间,但是效率要低很多。

     
  • 相关阅读:
    线性表---顺序表&链表
    C++——虚函数表——typedef指向函数的指针
    C++——继承与多态
    C++——动态内存分配new--delete
    C++——模板---函数模板---类模板
    C++——指针---指向数组的指针---指向字符串的指针--指向函数的指针--指针的指针--指针的引用
    C++——this指针
    C++——运算符的重载---以成员函数方式重载---以友元函数方式重载
    C++——友元函数--友元类——friend关键字
    Ubuntu环境下实现WireShark抓取HTTPS
  • 原文地址:https://www.cnblogs.com/sanshijvshi/p/10260636.html
Copyright © 2011-2022 走看看