P-States: Performance States,能效状态。 T-States:Throttling States。 S-States:Sleeping States,睡眠状态。 G-States:Global States,全局状态。 C-States:CPU States,处理器状态。 P-States指CPU根据当前运算负载,调整运行的频率。如2.6GHz的CPU,在系统空闲时,可以运行在1.8GHz频率。
READ MORE »Posts in category CPU基础
ARM64/ARMv8 CPU Cycle Counter/TSC值异常原因
在http://ilinuxkernel.com/?p=1755文章中,介绍了ARMv8/ARM64下读取CPU Cycle Counter/Time Stamp Counter值的方法,但在部分机器上测试,发现读取的值完全异常,不能真正反映CPU Cycle Counter真实值。
READ MORE »ARMv8/aarch64下TSC(Time Stamp Counter)读取方法
在x86架构中,我们对Time Stamp Counter (TSC) 寄存器非常熟悉,通过这个寄存器对代码执行时间的衡量可精确到CPU Cycle级别。 但在ARM/ARMv8/aarch64架构中,并没有与x86 TSC对应的寄存器和直接对应的汇编指令rdtsc。
READ MORE »[转]CPU微架构实现基础
来源:https://lagunita.stanford.edu/c4x/Engineering/CS316/ 下载:Processor Microarchitecture An Implementation Perspective Contents 1. Introduction ………………………………………………………………………………………….1 1.1 Classification of Microarchitectures ………………………………………………………….. 1 1.1.1 Pipelines/Nonpipelined Processors …………………………………………………. 1 1.1.2 In-Order/Out-of-Order Processors ………………………………………………… 2 1.1.3 Scalar/Superscalar Processors ………………………………………………………… 2 1.1.4 Vector Processors …………………………………………………………………………. 3 1.1.5 Multicore Processors …………………………………………………………………….. 3 1.1.6 Multithreaded Processors ……………………………………………………………… 3 1.2 Classification of Market Segments ……………………………………………………………. 3 1.3 Overview […]
READ MORE »ARM64浮点运算精度丢失问题
同样的代码,在ARM64和x86_64分别运行,发现部分计算结果从小数点后17位开始出现不同,双精度浮点运算结果有细微差异。 为了方便定位差异,我们编写一段简单浮点运算代码。 #include <math.h> #include <stdio.h> int main() { double dv[] = {-0.13942759833577333949961030157283, -0.046687081540714665817137785097657, -0.48496455527857718070805503884912, -0.60722091847450498924843032000354, 1, 1, 0, 0, -3.4221570491790771484375}; double dw[] = {0.019916933333333299710465880139054, -0.021317733333333300366208007403657, 0.13007783333333300390677322866395, 0.0013823433333333299752321288167423, 0.11358973333333299837732965897885, 0.21664233333333299258427473432675, -0.078728843333333298204479433479719, 0.31518266666666699959975517231214, 0.10316096666666700609749085515432 }; double dp = 0.0; int i = 0; for(i=0; i<9; i++){ dp += dv[i]*dw[i]; printf("\n========================"); printf("\ndv[%d]:%.32f ", i,dv[i]); printf("\ndw[%d]:%.32f ", i, […]
READ MORE »ARM64与x86_64浮点运算精度比较
浮点数(floating-point number)是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体来说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学记数法。 大部分计算机采用二进制(b=2)的表示方法。位(bit)是衡量浮点数所需存储空间的单位,通常为32位或64位,分别被叫作单精度和双精度。 浮点数精度标准有: IEEE 754 16-bit: Half (binary16) 32-bit: Single (binary32), decimal32 64-bit: Double (binary64), decimal64 128-bit: Quadruple (binary128), decimal128 Extended precision formats 计算机内部表示 Type Sign Exponent Significand field Total bits Exponent bias Bits precision Number of decimal digits Half(IEEE 754-2008) 1 5 10 16 15 11 […]
READ MORE »[转]Evolution of Intel’s Basic Microarchitectures
介绍Intel CPU微架构的演变。 1. Introduction 2. Core 2 3. Penryn 4. Nehalem 5. Nehalem-EX 6. Westmere 7. Westmere-EX 8. Sandy Bridge 9. Overview of the evolution 来源:http://users.nik.uni-obuda.hu//sima/oktatas.htm 下载:Evolution of Intel’s Basic Microarchitectures
READ MORE »Linux内核初始化时如何切换到64位模式
Linux内核初始化时,最初工作在CPU实地址模式下,然后进入保护模式。那么内核代码在哪里进入初始化CPU,让进入64位(x86_64)模式? Intel 64 CPU中,支持IA-32和IA-32e两种模式,如下图。IA-32e模式就是支持64位程序运行,也支持传统的32位程序运行。在Linux内核初始化时,要进入64位模式,就是进入Intel CPU的IA-32e模式。 本文以内核源码2.6.32-71.el6为例,切换到64位CPU模式源码在arch/x86/boot/compressed/head_64.S中。对于下面的设置步骤理解,可参考《Intel 64 and IA-32 Architectures Software Developer’s ManualVolume 3 (3A & 3B) System Programming Guide March 2011》. 这里补充一下IA32_EFER寄存器的含义。IA32_EFER寄存器是Intel CPU中的其中一个MSR(Model-Specific Registers)。在读写这个MSR寄存器之前,必须要先通过CPUID指令来确认这个寄存器是否存在。 00100: / * 00101: * Prepare for entering 64 bit mode 00102: */ 00103: 00104: / * Load new GDT with the 64bit segments using 32bit descriptor */ 00105: leal […]
READ MORE »x86/x86_64 CPU内存管理寄存器
x86/x86_64处理器提供了4个内存管理寄存器(Memory Management Registers):GDTR、LDTR、IDTR和TR。如下图所示。 Global Descriptor Table Register(GDTR) GDTR寄存器保存GDT的基址和表限(table limit)。基址是GDT的第一个字节的地址,表限(table limit)给出表的大小。 指令LGDT和SGDT是分别用来设置和保存GDTR寄存器的值。上电或重启处理器后,基址默认的值为0,表限(table limit)的值为0FFFFH。在保护模式运行前,作为处理器初始化的一部分,必须在GDTR寄存器中设置新的基址。 在Linux地址映射过程中,会用到GDTR寄存器。在此稍微详细介绍一下指令SGDT,即获取GDTR寄存器的值。SGDT指令的操作如下: Operation IF instruction is SGDT IF OperandSize = 16 THEN DEST[0:15] ← GDTR(Limit); DEST[16:39] ← GDTR(Base); (* 24 bits of base address stored *) DEST[40:47] ← 0; ELSE IF (32-bit Operand Size) DEST[0:15] ← GDTR(Limit); DEST[16:47] ← GDTR(Base); (* Full 32-bit […]
READ MORE »x86/x86_64 CPU控制寄存器(Control Registers)
x86/x86_64 CPU中提供了控制寄存器,来决定CPU的操作模式和当前执行任务的属性。这些寄存器在32位模式下是32bit,在64位模式中,控制寄存器扩展为64位。 CPU架构中共有CR0、CR1、CR2、CR3、CR4、CR8共6个控制寄存器,如下图。 各个控制寄存器的作用如下: CR0:包含当前处理器运行的控制标志。 CR1:保留。 CR2:包含发生页面错误时的线性地址。 CR3:页面目录表(Page Directory Table)的物理地址。 CR4:包含处理器扩展功能的标志位。 CR8:提供对任务优先级寄存器(Task Priority Register)的读写(仅在64位模式下存在)。 对控制寄存器的读写是通过MOV CRn指令来实现 下面代码(注意:本源码是32位系统)可用来读取CRn控制寄存器的值。 #include <linux/module.h> #include <linux/proc_fs.h> static char modname[] = “cr4″; static int cr4; static int my_get_info( char *buf, char **start, off_t off, int count ) { int len = 0; asm(” movl %cr4, %ebx \n movl %ebx, cr4 “); […]
READ MORE »