一.CPU发展历程
继电器 -> 晶体管 -> 门 -> 触发器/振荡器 -> 存储器 / 芯片(CPU)
继电器: 由铁丝围绕的铁棒(通电后改变磁性).可以表示0或1
晶体管: 固态半导体器件.如二极管/三极管.
已经被缩小到了1nm.
最初的电脑都是用继电器构成的.因为太大.所以后来使用晶体管代替.才发展成现在的笔记本这么小.
逻辑门: 由继电器或者晶体管构成.能表达一定的逻辑.
触发器: 可以保持一位信息.
可以通过多个相连.做成8位锁存器.32位锁存器.
振荡器: 由反向器构成(不停的通电断电).
如一次震荡(循环)需要0.05秒.那么他的频率就是20Hz.现在的电脑CPU一般都是2GHz以上了.
内存(RAM) / CPU: 由数百万至数亿个晶体管构成.
CPU: 寄存器/控制器/运算器/时钟
寄存器(关键): 用来暂存指令/数据.可以看作内存的一种.
控制器: 负责把内存上的指令/数据读入寄存器; 并根据指令的执行结果来控制整个计算机.
比如内存和磁盘等媒介的输入输出.键盘和鼠标的输入.显示器和打印机的输出等.都是控制的内容.
运算器: 负责运算从内存读入寄存器的数据.
时钟: 负责发出CPU开始计时的时钟信号.(时钟信号的频率越高.CPU的运行速度越快.现在的电脑基本是2GHz以上.即20亿次/秒)
内存
内存一般指的是计算机的主存储器.简称主存.
内存主要负责存储指令和数据.(可读.可写)
内存中每个字节(1byte == 8bit)都带有一个地址编号(指针指向的地址)
CPU可以通过地址编号读取内存中的指令和数据
主存的指令和数据会随计算机的关机而自动清除.
二.多核
可以把CPU理解成一套房子.中间的核心就是卧室.
一.超线程
你的房子本来是一室一厅的房子.
现在在你一室的房子中间用木板隔起来.就变成了两室一厅.
虽然变成了两室一厅.但是你房子的总面积并没有改变.
很多东西都是共用的.
超线程只是说把闲置的资源更充分的调动起来了.临时将一室变成两室
即临时超频变成单核双线程
二.双核心
双核心相当于找盖房子的又给你加盖了一件卧室.
变成了真正意义上的两室一厅.
你房子的总面积真的变大了.
但是客厅 / 厨房 / 大门你们都还是共用的.
双核心是真的增加了资源.提高了性能.但是因为还是有部分资源在共用.
即平常是双核双线程
超频时可以是双核四线程
三.双CPU
双CPU就相当于你名副其实的又两套房子.
两套房子里的所有资源都是独立的.
不过也可以看出双CPU消耗的钱也是最多的.
三.程序运行
每个程序运行后.操作系统都会给他指定一个开始位置.如地址0x010067ac.
此时操作系统就会将地址0x010067ac放入到程序计数器中.
程序计数器就会去地址0x010067ac取指令.
此刻你的程序就开始运行了.
如果前一次取出的指令仅是运算操作.那么程序计数器的值就会自动+1.
而如果前一次取出的指令的运算结果是跳转指令(跳转到其他指令地址).那么程序计数器的值就会加n.
一直这样下去.就是你的程序运行.
也就是说.程序计数器决定着程序的流程.
四. 解惑
对于多线程一直都不是很了解.所以就把平常想到的或者豁然开朗的小点记录下来.
就像最近我要做个功能.我想把他放子线程执行.但是大神说你放子线程执行节省的时间还不够切换上下文消耗的时间.脱了裤子放屁.
一.单核和多核
单核CPU上运行的多线程程序, 同一时间只能一个线程在跑, 系统帮你切换线程而已, 系统给每个线程分配时间片来执行, 每个时间片大概10ms左右, 看起来像是同时跑, 但实际上是每个线程跑一点点就换到其它线程继续跑.
这句话在原来机器只有单核的时候没毛病.但是现在机器基本都是多核CPU了.所以上面这句话就不对了.
iPhone4用的A4是单核.之后的iPhone最差都是双核了.到了iPhone7已经是四核了.
单核
多线程在单cpu中其实也是顺序执行的,不过系统可以帮你切换那个执行而已,其实并没有快(反而慢)
多核
只有在多核情况下多个线程才是真的在同时干活的.
解惑一: 线程切换的开销
如果单核情况下多线程是假象.会导致上下文切换(见附录1)的开销.
那多核情况下呢?
我想应该还是会有上下文切换的开销.或者操作系统内部开了多块高速缓冲区.
一个核心对应一个高速缓冲区.这样应该就不存在上下文切换了吧.
但是如果线程超过了核心数.应该还是需要上下文切换的.
解惑二: 但为什么有时候线程数超过CPU内核数会更快呢?
原因是这种程序的单个线程运算量不足以占满CPU一个内核(比如存在大量IO操作,IO比较慢,是程序瓶颈)。
解惑三: 为什么有时候多核情况下线程数多比单线程还慢呢?
其原因很简单.那就是读写锁/资源竞争的问题.如果在多个线程里需要读写同一个资源.那实际情况并不是并行执行.而是串行执行了.
解惑四: 什么时候使用多线程?
多线程的用处在于,做某个耗时的操作时,需要等待返回结果,这时用多线程可以提高程序并发程度。
如果一个不需要任何等待并且顺序执行能够完成的任务,用多线程简直是浪费。
五.附录
附录1.CPU上下文
因为CPU里只有那几十个寄存器.如果你切换了线程.那么寄存器里的信息也需要相应改变.
比如当前是A线程.寄存器里保存了AXXX信息.
当你切换到B线程时.寄存器需要先将A线程的AXXX信息保存起来.
然后读取B线程的BXXX信息.
这些AXXXX信息和BXXX信息即上下文.
附录2.寄存器的种类
种类 | 汇编助记符 | 个数 | 功能 |
---|---|---|---|
累加寄存器(accumulator register) | eax | 1 | 存储执行运算的数据和运算后的数据(用于运算的数值) |
标志寄存器(flag register) | 1 | 存储运算处理后的CPU的状态 | |
程序计数器(program counter) | 1 | 存储下一条指令所在内存的地址;CPU每执行一个指令.程序寄存器的值就会增加.增加的值为该指令长度相应的数值. | |
基址寄存器(base register) | ebp | n | 存储数据内存的起始地址 |
变址寄存器(index register) | n | 存储基址寄存器的相对地址 | |
通用寄存器(general purpose register) | n | 存储任意数据 | |
指令寄存器(instruction register) | 1 | 存储指令.CPU内部使用.程序员无法通过程序对该寄存器进行读写操作 | |
栈寄存器(stack register) | 1 | 存储栈区域的起始地址 | |
指令寄存器 | ? | 不需要程序员做多关注 |
附录3.汇编语言/机器语言种类
类型 | 功能 |
---|---|
数据转送指令 | 寄存器和内存; 内存和内存; 寄存器和外围设备之间的数据读写操作 |
运算指令 | 用累加寄存器执行算数运算.逻辑运算.比较运算和移位运算 |
跳转指令 | 实现条件分支.循环.强制跳转等 |
call/return指令 | 函数的调用/返回调用前的地址 |
网友评论