字节对齐的原因
硬盘对齐方法?
硬盘对齐方法?
传统硬盘的每个扇区固定是512个字节,新标准的“4K扇区”的硬盘,硬盘厂商为了保证与操作系统的兼容性,也将扇区模拟成512扇区,这时就会有4K扇区和4K簇不对齐的情况发生。 所以就要用“4K对齐”的方式,将硬盘模拟扇对齐成“4K扇区”。 “4K对齐”就是将硬盘扇区对齐到8的整数倍个模拟扇区,即512B*84096B,即是4K。
用win7系统对硬盘格式化时,默认是将硬盘扇区对齐到2048个扇区的整数倍,即512B*20481048576B1024KB,即1M对齐,并满足4K对齐,该值只要是4096B的倍数就是4K对齐。
centos6使用fdisk进行分区时要注意,默认开始扇区是不对齐的,centos7的fdisk进行分区,默认开始扇区是对齐的。
“4K”对不齐是因为在NTF6.x以前的规范中,数据的写入点正好介于在两个4K之间,也就是说即使是写入最小量的数据,也会使用到两个4K扇区,这样对写入速度和读取速度斗湖造成很大影响,为此对于“4K不对齐”的情况来说,一定要修改成“4K对齐”才行,否则对于固态硬盘来说,不但会极大的降低数据写入和读取速度,还会造成固态硬盘不必要的写入次数。
为什么系统类型是32位而内存的数据宽度显示是64bit?
内存编址方式的定义
数据总线宽度,决定了通过单次读或写操作,可访问的内存单元的粒度,比如说 8bit 数据总线宽度对应一个字节
地址总线宽度,决定了最大可访问的内存单元的个数,比如 32bit 地址总线宽度,对应 4G(注意不是 4GB)个内存单元
编址空间,由以上两者共同决定的可访问内存的空间范围,比如 8bit 数据宽度 32bit 地址宽度,决定 4GB 编址空间。
编址方式,决定了内存单元与内存控制器之间通过怎样的总线相连,以及内存控制器如何访问内存,举例说明:
金士顿 2GB 内存条,数据总线宽度 32bit,地址总线宽度 29bit
在内存条插到主板上并工作后,实际上内存编址方式为:数据总线宽度 32bit,地址总线宽度 29bit,内存条通过 32bit 的数据总线 29bit 的地址总线与 CPU 内部或主板上的内存控制器相连。
内存控制器访问内存时,需要送出 32bit 的数据总线信号和 29bit 的地址总线信号。
处理器寻址的定义
数据寻址粒度,指通过内存访问指令单次读或写可访问的内存单元的大小,比如 x86 上为一个字节
程序寻址粒度,由指令的长度决定,比如 x86 上为一个字节
数据寻址空间,由数据寻址粒度和指针寄存器宽度共同决定,比如 x86 上为 4GB
程序寻址空间,由程序寻址粒度和程序计数器宽度共同决定,比如 x86 上为 4GB
处理器寻址,包含两个方面,一个是数据寻址,另一个是程序寻址。
数据寻址是指执行内存访问指令时的寻址过程
程序寻址是指处理器内部在取指令和执行指令过程中的寻址
我们常说的寻址能力,一般指仅通过处理器本身的指令就可访问的内存空间。
编址与寻址的区别
内存控制器往下,是编址的概念,往上是寻址的概念,不可混淆。在汇编语言里,我们通常都说是寻址,而不是编址。
现在的主流计算机系统里,编址方式基本上都是采用 32bit 编址,而寻址都是按字节寻址。如果大家同意以上的定义,那么我们会发现问题本身就不合理,需修改。
接下来回答下问题
如果内存控制器的数据总线 32bit 地址总线 32bit,那么编址空间为 16GB。处理器能否寻址这 16GB 空间呢?就要看是否有对应的指令接口,或者 I/O 接口。众所周知的是 32bit 处理器有 4GB 的访问限制,但是并不是说不能突破这个限制,曾经的实模式 DOS 还有 64KB 限制和 1MB 限制,但实模式 DOS 下仍然可以突破限制访问 4GB。怎么突破限制,一是看内存控制器是否支持 4GB 以上的编址空间和处理器是否提供了特殊的内存访问指令,二是看是否可以通过 I/O 方式来突破。不过就算能突破限制,也存在诸多不便,比如读写性能受限,在 c 语言里没法方便的使用指针来访问内存,无法在这样的内存里面放入程序代码并执行等等。如果玩过实模式 DOS 下的 EMS、XMS 就深有体会了。所以既然有了彻彻底底的 64bit 处理器和操作系统,又何必去受这个苦呢。有答主认为采用 32bit 编址没法避免内存浪费,他理解的编址应该是我这里说的寻址。如果程序和数据都是以 32bit 的粒度寻址,那么的确可能导致浪费,因为这会导致指令的长度变为四字节对齐。但事情也不是绝对的,假定我们只能以 32bit 来进行程序寻址,那么意味着我们的跳转指令的地址(以字节为单位)的低两位就是 00,就是说跳转地址需要四字节对齐。而顺序执行的程序块里,可以保证里面的指令长度为最小的一个字节,处理器取指令的时候可以分离出正确指令的。就是说在不存在跳转指令的程序块里是完全可以避免浪费的,这样浪费只存在于程序块与程序块之间。事实上是当今的编译器,在编译 C 代码时,都会保证函数入口地址四字节对齐,甚至出于优化目的插入 nop 来保证指令对齐。另一方面,现在的大内存条件下,native 代码本身占用的内存空间已经很小,就算是存在空间浪费也不是主要矛盾。至于说兼容性也不是问题,既然 x64 可以兼容实模式、保护模式、64 位模式,再加一个模式并定义一个规范标准,技术上本来是可以行的,只是这样做的意义真的不大。(技术问题都是可以讨论的,可有些人真是说不得,惹急了就删回复,汗!)