计算机组成原理之内存数据的组织格式
1、存储字长
存储字长:存储单元中的二进制代码(存储字)位数,存储字长可以是8位、16位、32位等。
早期计算机的存储字长一般和机器的指令字长与数据字长相等,故访问一次主存便可取一条指令或一个数据。随着计算机的应用范围的不断扩大,解题精度的不断提高,往往要求指令字长是可变的,数据字长也要求可变。为了适应指令和数据字长的可变性,其长度不由存储字长来确定,而由字节的个数来表示。1个字节(Byte)被定义为由8位(Bit)二进制代码组成。
字长是根据当前的操作系统是有关系的,如果操作系统是64位的,那么表示的是有64根地址总线来进行控制,每个能够定位到多少个0101数据,然后通过数据总线运送数据到CPU中来进行执行。
ISA:
指令集架构(英语:Instruction Set Architecture,缩写为ISA),又称指令集或指令集体系,是计算机体系结构中与程序设计有关的部分,包含了基本数据类型,指令集,寄存器,寻址模式,存储体系,中断,异常处理以及外部I/O。指令集架构包含一系列的opcode即操作码(机器语言),以及由特定处理器执行的基本命令。
解决上面的问题:
2、数据存储和边界的关系
从上面可以看到在32位的操作系统中,连续的4个字节(32位01数字组合)放在一起,表示的是32位操作系统。
按照边界对齐的意思就是在连续的四个字节中,找到能够放得下当前的字节数的。如果放不下,就另起一行来存放当前数据。
对于i、k、x、c和j来取地址,获取得到的都是连续存放的字节的首地址内存单元编号。比如说i占据的是连续的四个字节,在对其进行取地址操作之后,返回的只是连续4个字节的第一个字节的地址编号。
从这种方式上来说,可以看到有三个字节的数据没有被利用。
3、未按照边界对其的数据存储
在这种方式中,值需要找到能够进行存储的对应的即可。但是对于操作系统来说,CPU和内存之间的交互次数又会增加。
这种方式下会以性能来换取空间的方式。上面的方式是交互两次,而现在这种方式会交互三次。
因为对于32位的操作系统来说,表示的是一次性可以读取32位01所能够表示的位数,如果按照上面的未按照边界来进行对齐,那么读取变量x可以一次性读取完,但是在读取变量x的时候,需要读取三次;在读取变量j的时候,需要来读取两次
在按照边界进行对齐的情况下,明明只需要读取到一次,而未按照边界对齐的情况下,各种情况都不相同。
4、数据存储和边界的关系
4.1、重点说明
参考博文:https://blog.csdn.net/WWIandMC/article/details/105215361?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163342133416780274149240%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163342133416780274149240&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-5-105215361.pc_search_ecpm_flag&utm_term=%E5%8F%8C%E5%AD%97%E9%95%BF%E6%95%B0%E6%8D%AE%E8%BE%B9%E7%95%8C%E5%AF%B9%E9%BD%90%E7%9A%84%E8%B5%B7%E5%A7%8B%E5%9C%B0%E5%9D%80%E7%9A%84%E6%9C%80%E6%9C%AB%E4%B8%89%E4%BD%8D%E4%B8%BA000&spm=1018.2226.3001.4187
因为双字长类似double这种数据类型,单字长的类似int这种数据类型,对于半字长边界对齐的类似char这种数据类型,
但是对于半字节的数据存储来说,要是想存储的是1这个数字,计算机中的其实地址的最后一位不应该是1吗?
答案:真的是找了好多篇博客来对这里的内容来进行讲解,终于算是领悟到了一点东西出来。
c/c++的数据类型要求边界对齐(实际上这是由存储器的结构)决定的,并不是语言本身的特性)。
处理器的数据线的根数决定了处理器的处理字长。
如上图左侧所示,内存是按字节为单位编址并按顺序排列,如果内存按照“一个存储体,每个单元的宽度”为一个字节”的方式来组织的话,处理器需要4个总线周期来读取一个4字节数据。
但实际上,并没有必要花4个总线周期来读取,我们有办法让处理器用1个总线周期完成读取——采用低位多体交叉存储结构(如上图右侧所示)。
尽管我们把内存空间分成了4个部分,但寻址的时候是仍然是把内存空间当成上图左侧那样连续的空间。
如果把双字数据的最低的8位放在Bank 0的X地址(X是一个能被16整除的偶地址)
X+3 | X+2 | X+1 | X |
---|---|---|---|
如果一个int类型的数据的起始存储位置能够被4整除,处理器在一个总线周期就能够读取完整个int。
然而,如果一个int的起始存储位置的地址不能被4整除,如下图:
处理器读取时,就需要扫描两行,需要2个总线周期完成。
不同数据类型的边界对齐要求
short ( 2 bytes ) | int ( 4 bytes ) | double ( 8 btyes ) |
---|---|---|
存储在Bank 0和Bank 1 | 占用存储体一行的空间,从低位到高位,依次存放在Bank 0,Bank 1,Bank 2,Bank 3 | 32位机器:占用存储体两行的空间。需要两个总线周期来读取。 |
存储在Bank 2和Bank 3 | 64位机器:存储体分成8个部分,一次能够处理64位数据,只需要1个总线周期。 |
如果一个int类型的数据的起始存储位置能够被4整除,处理器在一个总线周期就能够读取完整个int。
如果一个double类型的数据的起始存储位置能够被8整除,处理器在一个总线周期就能够读取完整个double。
等等,依次进行类推。那么对于short类型这种数据类型来说,就是被2整除,处理器就可以在一个总线周期中读取完整个short类型。
在对齐情况下,对于s1来说,占用的是12个字节;但是对于s2来说,占用的是9个字节。这种采用对其的是否效率高呢?
看看右边的图,如果要是以数组的方式存在,从右边图中可以看到,对于d[1]和d[2]来说,每个结构体结点都将会浪费3个字节,这种效果也是不好的。
5、大端和小端
最高字节地址和最低字节地址的划分?
6、大端和小端的存储方式
这种也只是一种程序设计的方式。
7、内存中边界对齐有什么用
从处理器的角度来看,需要尽可能减少对内存的访问次数以实现对数据结构进行更加高效的操作。为什么呢?因为尽管处理器包含了缓存,但它在处理数据时还得读取缓存中的数据,读取缓存的次数当然是越少越好!如上图所示,在采用边界对齐的情况下,当处理器需要访问a_变量和b_变量时都只需进行一次存取(图中花括号表示一次存取操作)。若不采用边界对齐,a_变量只要一次处理器操作,而b_变量却至少要进行两次操作。对于b_,处理器还得调用更多指令将其合成一个完整的4字节,这样无疑大大降低了程序效率。
8、测试题
1、设存储字长为64位,对 short 变量长度为16位,数据存储按整数边界对齐,关于short 变量 j 在主存中地址的下列描述中正确的是( ) (此题为多选题)
A.j的物理地址 mod 8 = 0
B.j的物理地址 mod 8 = 1
C.j的物理地址 mod 8 = 2
D.j的物理地址 mod 8 = 3
正确答案是:AC
因为对于short数据类型,长度是16位,也就是2个字节,那么64位操作系统要是想在一个操作周期内来找到,那么要求的是起始地址的最末位代表的二进制能够被2来进行整除,也就是是2的倍数;所以进行取模运算之后,应该是0、2、4这三个数字
2、设存储字长为64位,对 char 变量长度为8位,数据存储按整数边界对齐,关于char 变量 j 在主存中地址的下列描述中正确的是( ) (此题为多选题)
A.j的物理地址 mod 8 = 0
B.j的物理地址 mod 8 = 1
C.j的物理地址 mod 8 = 2
D.j的物理地址 mod 8 = 3
正确答案是:ABCD
对于char类型来说,占据8位,是一个字节,那么说明可以存储在连续的四个位置的任意地方,因为可以在任何地方都可以来进行存储。
对于char和byte数据类型来说,边界对齐的约束是无效的,哪里可以进行存储,就可以往哪里来进行存放。
所以起始地址应该是1的倍数,那么对于上述的四种选择,都是可以的。
3、下列关于大端与小端模式的描述中,正确的是 ( ) (此题为多选题)
A.大端模式(Big-endian)是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中
B.小端模式(Little-endian)是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中
C.0x12345678 按大端模式存放时,其所在存储单元最低字节单元存放的数据是0x12
D.0x12345678 按小端模式存放时,其所在存储单元最高字节单元存放的数据是0x12
正确答案是:ABCD
这里也正确的来描述了大端模式和小端模式的概念。
大端模式是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中;
小端模式是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中;
所以大端还是小端,只需要根据小端来进行对应即可。小端是数据低位放在内存低位,数据高位放在内存高位;
而大端是数据低位放在内存高地址中,数据高位放在的是内存低地址中;
从CD选项上,我们来进行判断一下:
对于0x12345678这种数据,低位确定的是后面的,高位确定的是前面的。
0x12345678 按大端模式存放时,其所在存储单元最低字节单元存放的数据是0x12
0x12345678 按小端模式存放时,其所在存储单元最高字节单元存放的数据是0x12
4、下列关于存储字长的描述中正确的是( ) (此题为多选题)
A.主存一个单元能存储的二进制位数的最大值
B.存储字长与所存放的数据类型有关
C.存储字长等于存储在主存中数据类型包含的二进制位数
D.存储字长一般应是字节的整数倍
正确答案:AD
存储字长是和操作系统的设计相关的,不和其中的内存单元中的二进制位数有关。因为有了个先来后到的区别。
5、某计算机按字节编址,数据按整数边界存放,可通过设置使其采用小端方式或大端方式,有一个float 型变量的地址为 FFFF C000H ,数据 X = 12345678H,无论采用大端还是小端方式,在内存单元 FFFF C001H,一定不会存放的数是 ( ) (此题为多选题)
A.12H
B.34H
C.56H
D.78H
正确答案:AD
12345678H数据高位和数据低位是从左边往右边的。
如果是按照小端,那么低位应该是12H,高位是78H;
如果是按照大端,那么低位应该是78H,高位应该是12H;
那么对应的是第一个地址,那么就应该开始往后面移动:
小端来说,低位是34H;大端来说56H
所以综合对比,一定不会是AD