指令周期

Intel Core i7的整体操作

不问归期 提交于 2020-03-09 08:10:20
Intel Core i7的整体操作(我们也称呼为Nehalem,他的项目代码名) 主要分成2个部分 -指令控制单元Instruction Control Unit(ICU),负责从存储器读出指令序列,并生成基本操作 -执行单元Execution Unit(EU),执行ICU生成出来的操作 ICU从指令高速缓存(Instruction Cache)中读取指令 通常会很早之前就取值,这样才有时间对指令译码,然后把操作发送给EU 不过如果遇到分支,会有2种情况 -选择分支,控制被传递的分支目标 -不选择分支,控制被传递到指令序列的下一条指令 现代处理器有了一种新技术叫分支预测 -处理器会预测是否会选择分支,并预测好分支的目标地址 -然后用投机执行Speculative Execution来取出位于它所预测会跳到的指令,然后译码(在还没确定预测是否正确前就执行了) -如果预测失败,就会回到分支点(重新预测) 指令译码逻辑接受实际的程序指令,并转换成基本操作(也叫微操作) -这些基本操作就是一些简单的计算任务 EU接受来自ICU的操作 -每个周期都会接受多个操作,这些操作会被分派到一组功能单元中,然后执行 -功能单元是用来处理特定类型的操作 读写存储器是由加载和存储单元实现 -加载单元处理从存储器读数据到处理器的操作 -当使用投机执行技术时,分支操作会送到EU,如果分支预测错误

关于单CPU,多CPU上的原子操作

五迷三道 提交于 2020-03-09 04:19:06
所谓原子操作,就是"不可中断的一个或一系列操作" 。 硬件级的原子操作: 在单处理器系统(UniProcessor)中,能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。这也是某些CPU指令系统中引入了test_and_set、test_and_clear等指令用于临界资源互斥的原因。 在对称多处理器(Symmetric Multi-Processor)结构中就不同了,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。 在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的 原子性。 软件级的原子操作: 软件级的原子操作实现依赖于硬件原子操作的支持。 对于linux而言,内核提供了两组原子操作接口:一组是针对整数进行操作;另一组是针对单独的位进行操作。 2.1. 原子整数操作 针对整数的原子操作只能对atomic_t类型的数据处理。这里没有使用C语言的int类型,主要是因为: 1)

并发编程和并行编程有什么区别?

风流意气都作罢 提交于 2020-03-08 18:16:49
并行编程和并行编程有什么区别? 我问谷歌,但没有找到任何可以帮助我理解这种差异的东西。 你能给我两个例子吗? 现在,我找到了以下解释: http : //www.linux-mag.com/id/7411- 但是“并发是程序的属性”与“并行执行是机器的属性”对我来说还不够-我还是不能说什么。 #1楼 我在一些博客中找到了此内容。 认为它是有用和相关的。 并发和并行性不是一回事。 如果未预先确定两个任务的执行顺序,则两个任务T1和T2是并发的, T1可以在T2之前执行并完成,T2可以在相同时间(并行)同时执行T1,T1和T2之前执行并完成,T1和T2可以交替执行,...如果有两个并发线程如果操作系统将其调度为在一个单核非SMT非CMP处理器上运行,则可能会并发但不会并行。 并行可能在多核,多处理器或分布式系统上进行。 并发通常被称为程序的属性,并且是比并行性更笼统的概念。 资料来源: https : //blogs.oracle.com/yuanlin/entry/concurrency_vs_parallelism_concurrent_programming #2楼 我相信并发编程是指多线程编程,它是让您的程序运行从硬件详细信息中抽象出来的多个线程。 并行编程是指专门设计程序算法以利用可用的并行执行。 例如,您可以并行执行某些算法的两个分支

Vue.js 创建一个 CNODE 社区(5)

纵然是瞬间 提交于 2020-03-07 07:56:38
自定义指令 demo: JSbin 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。 这篇博客写得略水,因为差不多都是 Vue官方文档 上有的内容,自己只不过是跟着demo敲了一遍,也算是温习一下吧~ 基本用法 和组件类似分全局注册和局部注册,区别就是把component换成了derective 钩子函数 指令定义函数提供了几个钩子函数(可选): bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。 inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document中)。 update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。 componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。 unbind: 只调用一次, 指令与元素解绑时调用。 钩子函数参数 el: 指令所绑定的元素,可以用来直接操作 DOM 。 binding: 一个对象,包含以下属性: name: 指令名,不包括 v­ 前缀。

操作系统精髓与设计原理笔记(1)

£可爱£侵袭症+ 提交于 2020-03-07 00:01:37
计算机系统概述 1.1基本构成 计算机基本构成:处理器、存储器、输入/输出部件 处理器:逻辑处理单元,控制计算机的操作,执行数据处理功能,(CPU)。 内存:存储数据和程序。特点是易失性,关机后,存储器的内容就会丢失,通常被称为实存储器或主存储器。 输入/输出模块:在计算机和外部环境(外部设备(存储器设备:硬盘、通信设备和终端))之间移动数据。 系统总线:为处理器、内存和输入/输出模块间提供通信的设施。 寄存器简介: CPU使用的寄存器 存储器地址寄存器(MAR):确定下一次读写的存储器地址。 存储器缓冲寄存器(MBR)存放要写入存储器的数据或从存储器读取的数据。 输入/输出寄存器: 输入/输出地址寄存器(I/O AR)确定一个特定的输入/输出设备。 输入/输出缓冲寄存器(I/O BR)用于在输入/输出模块和处理器间交换数据。 1.2处理器寄存器 处理器包含一组寄存器,它们提供一定的存储能力,比内存访问速度快,但比内存的容量小。 用户可见寄存器:优先使用这些寄存器,可以减少使用机器语言或汇编语言的程序员对内存的访问次数。对高级语言而言,由优化编译器负责决定哪些变量应该分配给寄存器,哪些变量应该分配给内存。一些高级语言(如C语言)允许程序员建议编译器把哪些变量保存在寄存器中。 控制和状态寄存器:用以控制处理器的操作,且主要被具有特权的操作系统例程使用,以控制程序的执行。 1.2

计算机组成原理5-预测和冒险

做~自己de王妃 提交于 2020-03-06 17:30:28
1、 CPU 的流水线设计的三大冒险 结构冒险(Structural Hazard)、数据冒险(Data Hazard)以及控制冒险(Control Hazard)。 2、 结构冒险  结构冒险的本质是硬件层面资源的竞争。CPU 在同一个时钟周期,同时在运行两条计算机指令的不同阶段。但是这两个不同的阶段,可能会用到同样的硬件电路。 可以看到,在第 1 条指令执行到访存(MEM)阶段的时候,流水线里的第 4 条指令,在执行取指令(Fetch)的操作。访存和取指令,都要进行内存数据的读取。内存只有一个地址译码器的作为地址输入,那就只能在一个时钟周期里面读取一条数据,没办法同时执行第 1 条指令的读取内存数据和第 4 条指令的读取指令代码。解决这种资源冲突的本质方法就是增加资源,在 CPU 的结构冒险里面。对于访问内存数据和取指令的冲突,一个直观的解决方案就是内存分成两部分,让它们各有各的地址译码器。这两部分分别是存放指令的程序内存和存放数据的数据内存。 现代的 CPU 并不会直接读取主内存。它会从主内存把指令和数据加载到 高速缓存 中,这样后续的访问都是访问高速缓存。而指令缓存和数据缓存的拆分,使得 CPU 在进行数据访问和取指令的时候,不会再发生资源冲突的问题了。 3、 数据冒险 数据冒险是程序逻辑层面的事,有三种类型:分别是 先写后读 (Read After Write,RAW)、

《网络攻防》- 学习心得

巧了我就是萌 提交于 2020-03-04 12:47:07
目录 冯诺依曼体系结构理解 设计思路 图灵机的理解 图灵的生平 人工智能 程序=指令+数据 组成 运行机制 图灵完备 冯诺依曼体系结构理解 当前计算机主要是基于冯诺依曼体系结构设计的,下面就简单分析一下冯诺依曼体系结构的计算机是如何工作的,首先下面的图就是冯诺依曼体系结构图。 主要由五大部件组成 1.存储器用来存放数据和程序 2.运算器主要运行算数运算和逻辑运算,并将中间结果暂存到运算器中 3.控制器主要用来控制和指挥程序和数据的输入运行,以及处理运算结果 4.输入设备用来将人们熟悉的信息形式转换为机器能够识别的信息形式,常见的有键盘,鼠标等 5.输出设备可以将机器运算结果转换为人们熟悉的信息形式,如打印机输出,显示器输出等 冯诺依曼体系结构的指令和数据均采用二进制码表示;指令和数据以同等地位存放于存储器中,均可按地址寻访;指令由操作码和地址码组成,操作码用来表示操作的性质,地址码用来表示操作数所在存储器中的位置;指令在存储器中按顺序存放,通常指令是按顺序执行的,特定条件下,可以根据运算结果或者设定的条件改变执行顺序;机器以运算器为中心,输入输出设备和存储器的数据传送通过运算器。 然而现在的计算机基本以存储器作为中心 但是由于运算器和控制器在逻辑关系和电路结构上联系十分紧密,通常将它们合起来统称为中央处理器,简称CPU,把输入输出设备简称为I/O设备

计算机组成原理 - 计算机层次结构 和 性能指标(容量 + 速度)⭐

雨燕双飞 提交于 2020-03-04 10:22:59
计算机层次结构 简单层次结构 计算机: 软件 + 硬件 软件=应用软件+系统软件 计算机层次结构 计算机性能指标(容量+速度) 容量 总容量 = 存储单元个数 × 存储字长(bit) 1Byte = 8bit ∴ 总容量 = 存储单元个数 × (存储字长/8)Byte 存储体 MAR地址寄存器 存储单元个数 2^n 和 译码器对应地址线n条 n个二进制可以表示出多少种不同的状态? n=1 0,1 2^1 n=2 00,01,10,11 2^2 ...... n=10 ... 2^10 K n=20 ... 2^20 M n=30 ... 2^30 G n=40 ... 2^40 T 速度 机器字长/存储字长/指令字长 研究对象:ALU 引入概念: 机器字长: 计算机进行 一次整数 运算 ,所 能处理的 二进制数据的 长度位数 (最多能同时处理多少位) = 内部寄存器大小 计算精度 区别: 存储字长: 存储单元 所存储的二进制单元的 长度位数 指令字长: 指令 中所包含的二进制 长度位数 一般 指令字长是存储字长的整数倍 ,指令字长和存储字长都是字节的整数倍 CPU时间周期/主频/CPI/指令耗时/CPU执行时间 CPU时间周期:最小的时间单元 主频(CPU时间频率) = 1/CPU时间周期 CPI :执行一条指令,所需时钟周期 数目 该指令耗时 = CPI ×CPU时钟周期

Vue.js 自定义指令

ぃ、小莉子 提交于 2020-03-03 14:08:53
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。 下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>demo</title> </head> <body> <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script> <div id="demo"> <p>元素默认无焦点</p> <input type="text"> <p>使用v-focus的元素将自动获得焦点</p> <input type="text" v-focus> </div> <script> //注册全局指令v-focus Vue.directive("focus", { //当元素被插入到DOM中 inserted: function (el) { el.focus() } }) // 创建根实例 new Vue({ el: '#demo' }) </script> 指令定义函数提供了几个钩子函数(可选): bind : 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

对于流程优化的处理器架构

佐手、 提交于 2020-03-02 15:40:46
在过去的两年里,我学到了很多的代码优化方法的同事,在此汇总了什么。 优化处理器架构可以从下面几个方向展开:高速缓存命中。指令预测。数据预取,数据对齐,内存拷贝优化,ddr访问延迟。硬件内存管理优化,指令优化。叙述工具。 缓存未命中是处理器的主要性能瓶颈之中的一个。在FSL的powerpc上,訪问一级缓存是3个时钟周期,二级是12个,3级30多个。内存100个以上。一级缓存和内存訪问速度差30多倍。 我们能够算一下,假设仅仅有一级缓存和内存,100条存取指令。100%命中和95%命中。前者300周期,后者95*3+5*100=785周期,差了1.6倍。这个结果的前提是powerpc上每一个核心仅仅有1个存取单元,使得多发射也无法让存取指令更快完毕。 当然,假设未命中的指令分布的好,其中穿插了非常多别的非存取指令那就能够利用乱序多做些事情,提高效率。 怎么用代码提高缓存命中率?我们能够用指令预測和数据预取。 指令预測非经常见,处理器预測将要运行的一个分支,把兴许指令取出来先运行。 等真正确定推断条件的时候,假设预測对了,提交结果。假设不正确,丢掉预先运行的结果。又一次抓取指令。 此时,结果还是正确的,可是性能会损失。 有一个经常使用的指令预測机制叫btb(branch target buffer),大致方法是,对于跳转指令,把它近期几次的跳转结果记录下来