CPU

CPU,全称为中央处理单元(Central Processing Unit),是计算机的核心组件之一,也被称为计算机的大脑。CPU负责执行计算机程序中的指令,进行数据处理和控制计算机的各个部件

文章来源: DIGITIMES

中国流传一句话:“黑猫白猫,能捉老鼠的就是好猫”,这是从“结果”论英雄,套用于市场法则,此话也一点不虚。

不论“中国芯”是采取哪种架构:LINUX?X86?只要能获得市场消费者最终青睐,由中国企业自行设计开发、流片量产,在市场上能屹立不倒,在此阶段就已能算通过考验。

近两、三年来,中国芯代表“兆芯”就采取X86架构CPU战略,获得联想在内的计算机系统业者采用,市场知名度渐见成效。

兆芯副总裁傅城接受DIGITIMES访问表示,事实上CPU MIPS架构开发支出远低于X86芯片架构开发费用,X86芯片的研发费用更大。但他认为从市场接受度来说,在嵌入式封闭型利基市场,小众客户接受度不是问题,但在讲求高性能的个人计算机、服务器领域,X86架构仍是主流,这一点上,兆芯还是较具优势。

两岸智汇“中国芯”(三):结合晶圆代工先进平台 兆芯CPU欲登巅峰

“中国芯”路数各不同 但良性竞争是好事

兆芯这几年CPU的成绩着实令人刮目相看,善用合作优势互补,两岸合则两利。过去台湾地区威盛多年积攒CPU市场与开发经验,放大到神州市场,挥洒空间更广阔。

近日兆芯又获威盛新一轮投资3731.25万美元资金挹注,预为下一代CPU市场铺垫准备,傅城不讳言,中国人要自己开拓中国芯CPU市场是一条任重道远的漫漫之路。

面对不同路数如国产MIPS架构CPU的竞争,傅城很“乐观”。他说,这是一件好事,如果国产芯片都能在领域内良性竞争,从国家层面都是有利的。

然而,X86架构的兆芯已经让其他对手如龙芯形成一定压力。就因为这种紧迫感,让行业内对手也不断追求性能的提升与进步。 “不论最终整机系统厂家采用的是哪一家国产芯片,这么多品牌都在朝着中国芯CPU努力,积极构建产业生态,是好事”,傅城这么说。

两岸智汇“中国芯”(三):结合晶圆代工先进平台 兆芯CPU欲登巅峰

软硬件无缝搭配 CPU才能实现最佳操作

兆芯采取X86架构还“占了一个便宜”就是希望通过这条途径,芯片无缝接轨能进入普罗大众家庭与企业办公计算机系统。

对CPU来说,进入普罗大众家庭与企业办公计算机系统,是一件很艰难的事情,要综合考虑开发成本、芯片性能、市场接受度等环节,尤其个人计算机不再是新兴应用,想凸显国产芯片的优势去进行替换需求,相对困难。

X86架构提供了兆芯一个切入点,具备替代国际厂商同类芯片的条件。因为微软操作系统与许多个人、办公软件都兼具兼容性。这牵涉到CPU不仅仅要考虑上芯片本身的问题,更要考量终端客户在操作体验上这颗CPU能不能跑得很好?很顺?需要不断优化,操作系统与CPU要搭配得天衣无缝,才能发挥出最极致的状态。

傅城举例,WIN-TEL战略就是一个最佳例证,软硬件相配合,软件为硬件优化、硬件也为软件优化,相互搭配得完美达到最佳结果;这就不仅仅是单颗芯片开发的问题,而是需要构建一个成熟生态系统,很多产业环节工作要做。

除了设计 还有foundry工艺平台的掌握

傅城指出,除了软硬件兼容问题,还有一个主要的难点是在工艺方面国内晶圆厂尚难以实现CPU工艺的掌握。其实,CPU行业已经基本掌握了设计的技术,都持续往前走,但一颗高质量、高效能的CPU,其设计平台与工艺平台需要紧密结合,而CPU领域,目前国内fabless+foundry模式还是难敌IDM巨头英特尔落后甚远。

傅城进一步分析,英特尔IDM设计与工艺平台是整合在一起的,工艺平台几乎就是为CPU服务,可以及时、调试工艺技术达到符应CPU效能最大化;AMD尽管其制造平台已独立为GLOBALFOUNDRIES,但其为AMD CPU制造的14nm工艺两者也紧密相结合,AMD从未轻易放手。这都是CPU强者,设计与工艺平台相结合,提供给国产CPU最好的借鉴。

“如果工艺平台对CPU公司不能很好的支持,国产CPU的效能就会被大打折扣,有时候甚至起到反作用,这是一个问题。”傅城点出,国内最大的晶圆代工厂如台积电其最先进的工艺都致力于追求低功耗制程,但计算机的心脏CPU是高耗能芯片,更需要高性能(HP)工艺制程平台支持。

他坦言,兆芯CPU每天都追求追赶国外巨头的步伐能进一步缩小,但实际上距离国外巨头仍落后遥远。 “当然,这个过程里政府的支持也是必不可少的。”

兆芯当前与上海华力微电子合作,华力微其工艺处于28nm工艺阶段,预期下半年推出ZX-D芯片系列,傅城期盼,其生产HP芯片性能如果调校得出色,至少与台积电22nm低功耗工艺产出的芯片性能相距不远。而2018年“重头戏”将是 16nm CPU芯片ZX-E 8系列则与台积电量产合作。若能跨两岸行业优势,整合工艺平台与设计平台,再造中国芯的一个“小巅峰”并不遥远。

文章来源: DIGITIMES

围观 160

来源: http://www.tuicool.com/articles/YJfqUjV

最近在利用空余时间写一个兼容MIPS32指令集架构的CPU,尽管它和Intel的不同,但MIPS对nop指令的处理方式可以给你一点启发。

首先上过计算机体系结构课的你一定知道,现代CPU都采用流水线结构。在一个简单的五级流水的MIPS32处理器中,五级流水分别实现的逻辑操作是: 取指、译码、执行、访存、回写 。

CPU空操作的原理是什么?

(图片来自网络,侵删)

在取指阶段,cpu从内存中代码区读取指令,然后将其送入译码阶段进行译码。那么译码阶段做了什么呢?要了解这一点,我们先来看看指令本身长什么样子,以移位操作指令sll为例,其在汇编语言中的用法为:

sll rd, rt, sa

意思是将地址为rt的通用寄存器的值向左移sa位(空出来的位置用0填充),得到的结果保存到地址为rd的通用寄存器中。(寄存器在上面那张图中就是译码阶段上方的那个“Register file”方块)

这么一条汇编指令用32位二进制表达将会是这个样子:

CPU空操作的原理是什么?

译码阶段先通过前六位和后六位识别出它是SLL移位指令,然后从rt寄存器读取数据,将其与“sa”一起送入执行阶段,并且告诉执行阶段: “数据已经给你了,请利用这两个数据做移位操作,做完请保存在rd这个地址。”

这下清楚了,译码其实就是在识别、拆解指令码,并准备好数据(这个数据可能来自寄存器,也可能就来自指令)送给执行阶段去执行特定的计算。至于访存和回写在干什么,与此问题无关,就不做介绍了。

有意思的来了。 我们来看看nop指令长什么样吧:

CPU空操作的原理是什么?

没错, 全0 。这就有问题了,按照刚才SLL指令的说明,SLL指令是通过前六位和后六位唯一确定的,那么nop指令被送往译码阶段后,不就会被当成SLL指令么……你别说,还真是。

按照sll指令的译码和执行方案,nop指令会被解释成这样:

sll $0, $0, 0

意思是把地址为$0的寄存器的值拿出来,左移0位,再存到地址为$0的寄存器当中去……那么寄存器$0里保存着的是什么呢…… MIPS32架构规定$0的值只能为0。

所以nop指令被CPU当成sll指令做了一次无意义的移位操作,实际上等于什么都没做,只是占用了一级流水线,如@龚黎明大大所说,用来作流水线填充,白白占用1个T的等待时间。

围观 369

来源:玩转单片机

回到最初的问题,CPU是怎样访问内存的?简单的答案是,CPU执行一条访存指令,把读写请求发往内存管理单元。内存管理单元进行虚实转换,把命令发往总线。总线把命令传递给内存控制器,内存控制器再次翻译地址,对相应内存颗粒进行存取。之后,读取的数据或者写入确认按照原路返回。再复杂些,当中插入多级缓存,在每一层缓存都未命中的情况下,访问才会最终达到内存颗粒。

知道了完整的路径,那我们开始研究每一步中的硬件到底是怎么样的,读写指令到底是怎样在其中传输的。要了解硬件,首先要说下处理器。处理器的基本结构并不复杂,一般分为取指令,译码,发射,执行,写回五个步骤。而我们说的访存,指的是访问数据,不是指令抓取。访问数据的指令在前三步没有什么特殊,在第四步,它会被发送到存取单元,等待完成。当指令在存取单元里的时候,产生了一些有趣的问题。

第一个问题,对于读指令,当处理器在等待数据从缓存或者内存返回的时候,它到底是什么状态?是等在那不动呢,还是继续执行别的指令?

一般来说,如果是乱序执行的处理器,那么可以执行后面的指令,如果是顺序执行,那么会进入停顿状态,直到读取的数据返回。当然,这也不是绝对的。在举反例之前,我们先要弄清什么是乱序执行。乱序执行是说,对于一串给定的指令,为了提高效率,处理器会找出非真正数据依赖的指令,让他们并行执行。但是,指令执行结果在写回到寄存器的时候,必须是顺序的。也就是说,哪怕是先被执行的指令,它的运算结果也是按照指令次序写回到最终的寄存器的。这个和很多程序员理解的乱序执行是有区别的。我发现有些人在调试软件问题的时候,会觉得使用了一个乱序的处理器,那么可能会使得后面的代码先被执行,从而让调试无法进行。他们搞混了两个个概念,就是访存次序和指令完成次序。对于普通的运算指令,他们仅仅在处理器内部执行,所以你看到的是写回次序。而对于访存指令,指令会产生读请求,并发送到处理器外部,你看到的次序是访存次序。对于乱序处理器,可能同时存在多个请求,而其次序,是打乱的,不按原指令顺序的。但是此时,这些被发送到外部的读请求,并没有拿到返回结果,指令也没有完成。所以,这并不违反乱序执行顺序完成的原则。如果有前后两条读指令,没有数据相关性,哪怕是后面那条读的数据先被返回,它的结果也不能先写回到最终的寄存器,而是必须等到前一条完成后才可以。

对于顺序执行的处理器,同样是两条读指令,一般必须等到前一条指令完成,才能执行第二条,所以在处理器外部看到的是按次序的访问。不过也有例外,比如读写同时存在的时候,由于读和写指令实际上走的是两条路径,所以可能会看到同时存在。这个问题在引入更详细的硬件结构之后再展开。

还有,顺序处理器上,哪怕是两条读指令,也有可能同时存在两个外部请求。比如Cortex-A7,对于连续的读指令,在前一条读未命中一级缓存,到下一级缓存或者内存抓取数据的时候,第二条读指令可以被执行。所以说,乱序和顺序并不直接影响指令执行次序。他们的区别在于,乱序需要额外的缓冲和逻辑块(称为重排序缓冲, re-order buffer)来计算和存储指令间的相关性以及执行状态。而顺序处理器没有重排序缓冲,或者非常简单。这些额外的面积可不小,据我所看到的,可以占到处理器核心的40%。它们所带来的更高的并行度,性能提升却未必有40%。因为我们写的单线程程序,由于存在很多数据相关,造成指令的并行是有限的,再大的重排序缓冲也解决不了真正的数据相关。所以对于功耗敏感的处理器还是使用顺序执行。

还有一点需要注意,顺序执行的处理器,在指令抓取,解码和发射阶段,两条或者多条指令,是可以同时进行的。比如,无依赖关系的读指令和运算指令,可以被同时发射到不同的执行单元,同时开始执行。但是完成还是按顺序的。

但是,在有些ARM处理器上,比如Cortex-A53,向量或者加解密指令是可以乱序完成的,这类运算的结果之间并没有数据依赖性。这点请千万注意。
再来看看写指令。写和读有个很大的不同,就是写指令不必等待数据写到缓存或者内存,就可以完成了。写出去的数据会到一个叫做store buffer的缓冲,它位于一级缓存之前,只要它没满,处理器就可以直接往下走,不必停止并等待。所以,对于连续的写指令,无论顺序还是乱序执行处理器,都可能看到多个写请求同时挂在处理器总线上。同时,由于处理器不必像读指令那样等待结果,就可以在单位时间内送出更多写请求,所以我们可以看到写带宽通常是大于读带宽的。

以上所说的读写访问都是在开启缓存的情况,关闭的情况以后讨论。

对于同时存在的多个请求,有一个名词来定义它,叫做outstanding transaction,简称OT。它和延迟一起,构成了我们对访存性能的描述。延迟这个概念,在不同领域有不同的定义。在网络上,网络延迟表示单个数据包从本地出发,经过交换和路由,到达对端,然后返回,当中所花的总时间。在处理器上,我们也可以说读写的延迟是指令发出,经过缓存,总线,内存控制器,内存颗粒,然后原路返回所花费的时间。但是,更多的时候,我们说的访存延迟是大量读写指令被执行后,统计出来的平均访问时间。这里面的区别是,当OT=1的时候,总延时是简单累加。当OT>1,由于同时存在两个访存并行,总时间通常少于累加时间,并且可以少很多。这时候得到的平均延迟,也被称作访存延迟,并且用得更普遍。再精确一些,由于多级流水线的存在,假设流水线每一个阶段都是一个时钟周期,那访问一级缓存的平均延迟其实就是一个周期.而对于后面的二级,三级缓存和内存,就读指令来说,延迟就是从指令被发射(注意,不是从取指)到最终数据返回的时间,因为处理器在执行阶段等待,流水线起不了作用。如果OT=2, 那么时间可能缩短将近一半。OT>1的好处在这里就体现出来了。当然,这也是有代价的,存储未完成的读请求的状态需要额外的缓冲,而处理器可能也需要支持乱序执行,造成面积和功耗进一步上升。对于写指令,只要store buffer没满,还是一个时钟周期。当然,如果流水线上某个节拍大于一个时钟周期,那平均的延时就会取决于这个最慢的时间。在读取二级,三级缓存和内存的时候,我们可以把等待返回看作一个节拍,那么就能很自然的理解此时的延迟了。由此,我们可以得到每一级缓存的延迟和访存延迟。

上图画了读写指令经过的单元。我把流程简单描述下:
当写指令从存取单元LSU出发,它首先经过一个小的store queue,然后进入store buffer。之后,写指令就可以完成了,处理器不必等待。Store buffer通常由几个8-16字节的槽位组成,它会对自己收到的每项数据进行地址检查,如果可以合并就合并,然后发送请求到右边的一级缓存,要求分配一行缓存,来存放数据,直到收到响应,这称作写分配write allocate。当然,等待的过程可以继续合并同缓存行数据。如果数据是Non-Cacheable的,那么它会计算一个等待时间,然后把数据合并,发送到总线接口单元BIU里面的写缓冲Write buffer。 而写缓冲在把数据发到二级缓存之前,会经过监听控制单元,把四个核的缓存做一致性。过程和总线描述的类似,就不多讲了。

当读指令从存取单元LSU出发,无论是否Cacheable的,都会经过一级缓存。如果命中,那么直接返回数据,读指令完成。如果未命中,那么Non-Cacheable的请求直接被送到Read Buffer。如果是Cacheable的,那么一级缓存需要分配一个缓存行,并且把原来的数据写出到替换缓冲eviction buffer,同时发起一个缓存行填充,发送到Linefill Buffer。eviction buffer会把它的写出请求送到BIU里面的Write buffer,和Store Buffer送过来的数据一起,发到下一级接口。然后这些请求又经过监听控制单元做一致性检测后,发到二级缓存。当然有可能读取的数据存在于别的处理器一级缓存,那么就直接从那里抓取。

过程并不复杂,但程序员关心的是这个过程的瓶颈在哪,对读写性能影响如何。我们已经解释过,对于写,由于它可以立刻完成,所以它的瓶颈并不来自于存取单元;对于读,由于处理器会等待,所以我们需要找到读取路径每一步能发出多少OT,每个OT的数据长度是多少。
拿Cortex-A7来举例,它有2x32字节linefill buffer,支持有条件的miss-under-miss(相邻读指令必须在3时钟周期内),也就是OT最多等于2,而它的数据缓存行长度是64字节,所以每个OT都是半个缓存行长度。对于Cacheable的读来说,我还关心两个数据,就是eviction buffer和Write buffer,它们总是伴随着line fill。在A7中,存在一个64字节的eviction buffer和一个Write buffer。有了这些条件,那么我就可以说,对于连续的读指令,我能做到的OT就是2,而linefill的速度和eviction,write buffer的速度一致,因为2x32=64字节。

那这个结论是不是正确?写个小程序测试下就知道。我们可以关掉二级缓存,保留一级缓存,然后用以下指令去读取一个较大的内存区域。所有的地址都是缓存行对齐,对齐的意义我就不说了,不对齐,甚至越过缓存行边界,会把一个操作变成两个,肯定会慢。伪代码如下:
loop
load R0, addr+0
load R0, addr+4
load R0, addr+8
load R0, addr+12
addr=addr+16

这里通过读取指令不断地去读数据。通过处理器自带的性能计数器看了下一级缓存的未命中率,6%多一点。这恰恰是4/64字节的比率。说明对于一个新的缓存行,第一个四字节总是未命中,而后面15个四字节总是命中。当然,具体的延迟和带宽还和总线,内存控制器有关,这里只能通过命中率简单验证下。

对于有的处理器,是严格顺序执行的,没有A7那样的miss-under-miss机制,所以OT=1。我在Cortex-R5上做同样的实验,它的缓存行长度是32字节,2xLinefill buffer是32字节。测试得到的命中率是12%多点。也完全符合估算。

但是为什么R5要设计两个32字节长度的Linefill buffer?既然它的OT=1,多出来的一个岂不是没用?实际上它是可以被用到的,而方法就是使用预取指令PLD。预取指令的特点就是,它被执行后,处理器同样不必等待,而这个读请求会被同样发送到一级缓存。等到下次有读指令来真正读取同样的缓存行,那么就可能发现数据已经在那了。它的地址必须是缓存行对齐。这样,读也可像写那样把第二个 Linefill buffer给用上了。

我们把它用到前面的例子里:
loop
PLD addr+32
load R0, addr+0;...;load R0, addr+28;
load R0, addr+32;...;load R0, addr+60;
addr=addr+64

PLD预先读取第二行读指令的地址。测试发现,此时的未命中率还是6%。这也符合估算,因为第二排的读指令总是命中,第一排的未命中率4/32,平均下就是6%。而测试带宽提升了80%多。单单看OT=2,它应该提升100%,但实际不可能那么理想化,80%也可以理解。

还有一种机制使得OT可以更大,那就是缓存的硬件预取。当程序访问连续的或者有规律的地址时,缓存会自动检测出这种规律,并且预先去把数据取来。这种方法同样不占用处理器时间,但是也会占用linefill buffer,eviction buffer和write buffer。所以,如果这个规律找的不好,那么反而会降低效率。
读看完了,那写呢?Cacheable的写,如果未命中缓存,就会引发write allocate,继而造成Linefill和eviction,也就是读操作。这点可能很多程序员没想到。当存在连续地址的写时,就会伴随着一连串的缓存行读操作。有些时候,这些读是没有意义的。比如在memset函数中,可以直接把数据写到下一级缓存或者内存,不需要额外的读。于是,大部分的ARM处理器都实现了一个机制,当探测到连续地址的写,就不让store buffer把数据发往一级缓存,而是直接到write buffer。并且,这个时候,更容易合并,形成突发写,提高效率。在Cortex-A7上它被称作Read allocate模式,意思是取消了write allocate。而在有的处理器上被称作streaming模式。很多跑分测试都会触发这个模式,因此能在跑分上更有优势。

但是,进入了streaming模式并不意味着内存控制器收到的地址都是连续的。想象一下,我们在测memcpy的时候,首先要从源地址读数据,发出去的是连续地址,并且是基于缓存行的。过了一段时间后,缓存都被用完,那么eviction出现了,并且它是随机或者伪随机的,写出去的地址并无规律。这就打断了原本的连续的读地址。再看写,在把数据写到目的地址时,如果连续的写地址被发现,那么它就不会触发额外的linefill和eviction。这是好事。可是,直接写到下一级缓存或者内存的数据,很有可能并不是完整的缓存发突发写,应为store buffer也是在不断和write buffer交互的,而write buffer还要同时接受eviction buffer的请求。其结果就是写被分成几个小段。这些小块的写地址,eviction的写地址,混合着读地址,让总线和内存控制器增加了负担。它们必须采用合适的算法和参数,才能合并这些数据,更快的写到内存颗粒。

然而事情还没有完。我们刚才提到,streaming模式是被触发的,同样的,它也可以退出。退出条件一般是发现存在非缓存行突发的写。这个可能受write buffer的响应时间影响。退出后,write allocate就又恢复了,从而读写地址更加不连续,内存控制器更加难以优化,延时进一步增加,反馈到处理器,就更难保持在streaming模式。

再进一步,streaming模式其实存在一个问题,那就是它把数据写到了下一级缓存或者内存,万一这个数据马上就会被使用呢?那岂不是还得去抓取?针对这个问题,在ARM v8指令集中(适用于A53/57/72),又引入了新的一条缓存操作指令DCZVA,可以把整行缓存设成0,并且不引发write allocate。为什么?因为整行数据都被要改了,而不是某个字段被改,那就没有必要去把原来的值读出来,所以只需要allocate,不需要读取,但它还是会引发eviction。类似的,我们也可以在使用某块缓存前把它们整体清除并无效化,clean&invalidate,这样就不会有eviction。不过如果测试数据块足够大,这样只是相当于提前做了eviction,并不能消除,让写集中在某段。使之后的读更连续。

以上都是针对一级缓存。二级缓存的控制力度就小些,代码上无法影响,只能通过设置寄存器,打开二级缓存预取或者设置预取偏移。我在ARM的二级缓存控制器PL301上看到的,如果偏移设置的好,抓到的数据正好被用上,可以在代码和一级缓存优化完成的基础上,读带宽再提升150%。在新的处理器上,同时可以有多路的预取,探测多组访存模板,进一步提高效率。并且,每一级缓存后面挂的OT数目肯定大于上一级,它包含了各类读写和缓存操作,利用好这些OT,就能提高性能。

对于Non-Cacheable的写,它会被store buffer直接送到write buffer进行合并,然后到下一级缓存。对于Non-Cacheable的读,我们说过它会先到缓存看看是不是命中,未命中的话直接到read buffer,合并后发往下一级缓存。它通常不占用linefill buffer,因为它通常是4到8字节,不需要使用缓存行大小的缓冲。

我们有时候也可以利用Non-Cacheable的读通道,和Cacheable的读操作并行,提高效率。它的原理就是同时利用linefill buffer和read buffer。此时必须保证处理器有足够的OT,不停顿。

简而言之,访存的软件优化的原则就是,保持对齐,找出更多可利用的OT,访存和预取混用,保持更连续的访问地址,缩短每一环节的延迟。

最后解释一下缓存延迟的产生原因。程序员可能不知道的是,不同大小的缓存,他们能达到的时钟频率是不一样的。ARM的一级缓存,16纳米工艺下,大小在32-64K字节,可以跑在1-2Ghz左右,和处理器同频。处理器频率再快,那么访问缓存就需要2-3个处理器周期了。而二级缓存更慢,256K字节的,能有800Mhz就很好了。这是由于缓存越大,需要查找的目录index越大,扇出fanout和电容越大,自然就越慢。还有,通常处理器宣传时候所说的访问缓存延迟,存在一个前提,就是使用虚拟地址索引VIPT。这样就不需要查找一级Tlb表,直接得到索引地址。如果使用物理地址索引PIPT,在查找一级tlb进行虚实转换时,需要额外时间不说,如果产生未命中,那就要到二级甚至软件页表去找。那显然太慢了。那为什么不全使用VIPT呢?因为VIPT会产生一个问题,多个虚地址会映射到一个实地址,从而使得缓存多个表项对应一个实地址。存在写操作时,多条表项就会引起一致性错误。而指令缓存通常由于是只读的,不存在这个问题。所以指令缓存大多使用VIPT。随着处理器频率越来越高,数据缓存也只能使用VIPT。为了解决前面提到的问题,ARM在新的处理器里面加了额外的逻辑来检测重复的表项。

啰嗦了那么多,该说下真正系统里的访存延迟到底如何了。直接上图:

上图的配置中,DDR4跑在3.2Gbps,总线800Mhz,内存控制器800Mhz,处理器2.25Ghz。关掉缓存,用读指令测试。延迟包括出和进两个方向,69.8纳秒,这是在总是命中一个内存物理页的情况下的最优结果,随机的地址访问需要把17.5纳秒再乘以2到3。关于物理页的解释请参看内存一章。
在内存上花的时间是控制器+物理层+接口,总共38.9纳秒。百分比55%。如果是访问随机地址,那么会超过70纳秒,占70%。在总线和异步桥上花的时间是20纳秒,8个总线时钟周期,28%。处理器11.1纳秒,占16%,20个处理器时钟周期。

所以,即使是在3.2Gbps的DDR4上,大部分时间还都是在内存,显然优化可以从它上面入手。在处理器中的时间只有一小部分。但从另外一个方面,处理器控制着linefill,eviction的次数,地址的连续性,以及预取的效率,虽然它自己所占时间最少,但也是优化的重点。

在ARM的路线图上,还出现了一项并不算新的技术,称作stashing。它来自于网络处理器,原理是外设控制器(PCIe,网卡)向处理器发送请求,把某个数据放到缓存,过程和监听snooping很类似。在某些领域,这项技术能够引起质的变化。举个例子,intel至强处理器,配合它的网络转发库DPDK,可以做到平均80个处理器周期接受从PCIe网卡来的包,解析包头后送还回去。80周期是个什么概念?看过了上面的访存延迟图后你应该有所了解,处理器访问下内存都需要200-300周期。而这个数据从PCIe口DMA到内存,然后处理器抓取它进行处理后,又经过DMA从PCIe口出去,整个过程肯定大于访存时间。80周期的平均时间说明它肯定被提前送到了缓存。 但传进来的数据很多,只有PCIe或者网卡控制器才知道哪个是包头,才能精确的推送数据,不然缓存会被无用的数据淹没。这个过程做好了,可以让软件处理以太网或者存储单元的速度超过硬件加速器。事实上,在freescale的网络处理器上,有了硬件加速器的帮助,处理包的平均延迟需要200处理器周期,已经慢于至强了。

还有,在ARM新的面向网络和服务器的核心上,会出现一核两线程的设计。处理包的任务天然适合多线程,而一核两线程可以更有效的利用硬件资源,再加上stashing,如虎添翼。

围观 558

什么是单片机,相信很多人都还不知道。也不知道单片机的作用是什么。单片机简称为单片微控制器(Microcontroler),它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上,相当于一个微型的计算机,因为它最早被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对提及要求严格的控制设备当中。

大家都知道我们的电脑主要是由中央处理单元CPU(进行运算、控制)、随机存储器RAM(数据存储)、存储器ROM(程序存储)、输入/输出设备I/O(串行口、并行输出口等)。安装在一个被称之为主板的印刷线路板上,就是我们个人的计算机了。

把单片机看成一个整体分成四块就很容易认识了。 把这些东西(CPU,硬盘,内存,主板等等)用集成块做好后,如下图所视:

一文看懂单片机与CPU的相似与不同

单机片

就成了我们要学习的“单片机”了。而在单机片的内部,CPU,硬盘,内存,主板等等却又是另外的名字。

1)CPU(Central Processing Unit)。它是单片机的核心部件,包括运算器和控制器。运算器既是算术逻辑单元ALU(Arithmetic logic Unit),其功能是进行算术运算和逻辑运算。控制器一般由指令寄存器、指令译码器、时序电路和控制电路组成。起作用是完成取指令、将指令译码形成各种微操作并执行指令,同时控制计算机的各个部件有条不紊地工作。

一文看懂单片机与CPU的相似与不同

cpu内部图

2)计算机中的内存,在单片机里叫数据存储器,也叫随机存储器。用RAM(Random Access Memery)表示。其作用是用于存放运算的中间结果,数据暂存和缓冲,标志位等。特点是:掉电后会丢失数据。

一文看懂单片机与CPU的相似与不同

程序存储器

3)计算机中的硬盘,在单片机中,叫程序存储器,也叫只读存储器。用ROM(Read only memery)表示。其作用和硬盘差不多,用来存放用户程序。特点是:掉电后不会丢失数据。

4)输入/输出设备I/O“主板”,在单片机里,叫做I/O(输入输出设备)当然也包含了串行口,并行口,定时器,记时器等等。

一文看懂单片机与CPU的相似与不同

单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等。因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。

本文引用地址: http://www.eepw.com.cn/article/201702/343732.htm

围观 498

CPU就是在一张硅片上,刻几百万个晶体二极管。制成二极管,硅的开启电压(死区电压)需要0.5V,锗的开启电压只需0.1V。也就是锗CPU只需零点几的电压就能运行,比现在的1V低多了,也算CPU的革命吧。电压更低,意味发热量更少,集成度和频率可以更高。即便开发锗CPU有困难,也比脑动大开的 量子CPU, 光子CPU, DNA CPU靠谱吧?

硅用来做CPU,是因为它的优点太多,而缺点都是可克服的。锗虽然也有优点(比如开启电压、载流子迁移率),但它的几个缺点是很难克服的。

首先是价格。硅直接拿沙子就能制,虽然工艺复杂但是原料成本接近零,锗在地壳中分布非常分散,成品锗(还不是半导体级别)的价格就已经超越了白银,印象中将近2000美元/公斤。

其次很大一个问题就是锗的氧化物不稳定。二氧化硅是致密的绝缘体,力学电学化学性质都很稳定,不溶于水;氧化锗没那么致密,还是溶于水的。这一条基本就宣告了CPU无望。

还有锗器件在稍高的温度下表现不良的问题,以及锗本身比硅重、又比硅软、更容易碎等等。而且现在整个半导体行业都以硅为基础,没人会开发锗的CPU。

目前锗的前途很大程度上在光电学方面,如太阳能电池、光传感器、红外LED、锗激光器(这个已经被MIT做出来了,但不是大家想象中的激光笔那样子)。因为硅做激光完全不可能,锗又能比较容易地在硅上生长出来,因此大家的理想是将用锗做成的光学器件与硅做成的电子器件整合在一张硅片上,那就牛逼了。

再说一句,近三五年来锗基半导体方面进展很大,但是不少同行还没完全了解这些进展。如果看以前的书本上讲的一些关于生长锗的局限,现在很多都已经被攻克了。以前人们说在硅上没办法直接长锗,还有得用高温,或者需要几个GeSi的buffer,十年前确实是这样。但现在在三百多度的温度下直接在硅片上生长锗,出来的膜质量很不错。
1948年,世界上第一个点接触晶体管是用锗做的,就是这个样:

在遥远的上古时代(1950),那时候集成电路还没有发明,晶体管的分立器件就已经慢慢由锗变成了硅。这是为什么呢?

世界上第一个和第一个商用的双极结型晶体管都是用锗做的。摩托罗拉公司当时还是一家车载收音机的制造商。摩托罗拉是当时第一家使用晶体管来制造收音机的厂商。但是好景不长,摩托罗拉收到了大量用户投诉,说他们发现摩托罗拉的车载收音机在午后的阳光下曝晒一个下午后,就不再工作了。摩托罗拉被搞得焦头烂额,这从市场层面给了摩托罗拉公司很强的动力用硅替换锗来制造晶体管。
为啥会这样呢?因为锗在受热之后会变成本征态,这使得N型半导体和P型半导体都失去了他们特有的性质,那结果呢就是双极结型晶体管不能再工作了。而硅可以经受更高温度的考验。

硅取代锗其实是历史的必然,让我们来看看硅棒棒的性质吧:

有着和钻石一样棒的晶体结构,这赋予了硅极好的稳定性和强度;超棒的队友二氧化硅(SiO2),用简单的炉式氧化法就可以得到非常高质量的二氧化硅,而且界面态很少。啥是炉式氧化法呢?大概就和烤面包差不多,类似你把硅片放到一个充满氧气的烤箱里去烤一下。硅的带隙更大,具有更好的热稳定性,硅材料便宜啊,硅都是沙子提炼出来的,想想地球上有多少沙子可以用吧!还有一点非常重要!锗CPU 75度以上就不能工作了。。。

来源: 周立功单片机

围观 377

Atmel 外设触摸控制器是电容式触摸传感模块,支持 1-256 信道的自主传感。PTC 支持在相同应用内进行自电容和互电容传感器布局,这就为系统设计师提供了极高的灵活度。由于自主运行,PTC 只使用了微乎其微的 CPU 资源和电,即使是面对高 Key Count 的设计时。凭借嵌入式自动调谐和校准,PTC 将提供高质量的触摸性能,即使是在恶劣环境下。因此,有 PTC 的 MCU 是所有触摸应用的理想之选。Atmel Studio 支持代码开发和调试。对于有高集成和触摸性能要求的任何应用来说,有 PTC 的 MCU 无疑都是不二之选。PTC 可从特定 SMART ARM 设备获取。

关键特性
• 支持按钮、滑条、滑轮和触摸表面 — 触摸信道最高可达 256(视包的情况而定)
• 支持互电容和自电容触摸,即使此时并无外部组件需求
• 自校准,无调谐需求
• 自主运行,低 CPU 负载 极低的功耗
• 在恶劣环境下运行时有出众的抗传导干扰性 (CI)

ATmega328PB
关键特性
• 额外 USART:新增一个具有帧起始检测功能的 USART,可用于从休眠模式下唤醒 MCU(共两个)。
• 额外定时器/计数器:增加了两个 16 位定时器/计数器,这些器件新增独立预分频器、比较模式和捕获模式(共三个)。
• 唯一序列号:每个器件都具有唯一的 10 字节序列编号,可从应用软件中读出。 这种编号用途广泛,从物流跟踪到加密功能,在通信网络中用作器件地址,使该器件非常适用于任何一种 IoT 应用。
• 额外 SPI:增加一个主/从 SPI(共两个)。
• 更多 IO:32 引脚 megaAVR 器件将 GPIO 数量从 23 个增加到 27 个
• 在引脚 3、6、19 和 22 上新增 Port E 模拟比较器输出 - 现在,这些器件使得在引脚 3 上获得模拟比较器输出成为可能。
• 模拟性能增强 - 内部电压基准和内部振荡器提升了精度,可增强任何 ADC 测量性能,实现更高的串行通信速度。

SAM D MCU
关键特性
• 低功耗 — 市场领先的省电技术包括事件系统,可使外设直接相互通信,而无需 CPU 干预。此外,Atmel SleepWalking 外设只有在发生预先限定的事件时才唤醒 CPU,从而降低了整体功耗。
• 外设灵活性 — 创新的串行通信模块 (SERCOM) 可以在软件中进行全部配置,以便处理 I2C、USART/UART 和 SPI 通信。借助器件上的多个 SERCOM 模块,可以在您的应用中精确地定制外设组合。SAM D 21 上的 I2C 的工作频率高达 3.4 MHz(也支持 I2S、PMBus 和 SMBus)。SAM D11 和 SAM D10 还支持 IrDA。
• DMA — SAM D21 MCU 配有支持内存和外设数据传输的 8 通道 DMA 控制器,而 SAM D11 和 SAM D10 则是配有 6 通道 DMA 控制器。 高管脚利用率 — SAM D11 只需要一个电源对,最大程度地提高了可供您的应用使用的管脚数。
• 全速 USB — SAM D21 既支持 USB 嵌入式主机又支持 USB 设备模式,而 SAM D11 则支持全速 USB 设备模式。在设备模式下可以使用内部 RC 振荡器支持全速 USB,从而降低了 BOM 成本和设计复杂性。
• Atmel QTouch® 外设触摸控制器 — 可为按钮、滑条、滑轮和近距离感应提供内置的硬件支持,并支持互电容式和自电容式触摸,而无需外部元件。它具有卓越的灵敏度、耐噪性以及自校准功能,任何用户都可以调整余量。
• 可扩展性 — 闪存密度范围从 8KB 到 256KB,封装范围从 14 管脚到 64 管脚选项。

SAM L MCU
关键特性
• 低功耗 — 市场领先的省电技术包括 12 通道事件系统,可使外设直接相互通信,而无需 CPU 干预。Atmel Sleepwalking 外设可以给时钟和功率设限,从而减少漏电和转换,且仅在出现指定事件时唤醒 CPU,在活动模式中实现 35 uA/MHz 的超低功耗,ULPBench 分数达到 185.8,减少整体功耗。
• 外设灵活性 — 创新性的串行通信模块 (SERCOM) 完全可以在软件中进行配置,以便处理 I2C、USART/UART 和 SPI 通信。借助器件上的多个 SERCOM 模块,可以在您的应用中精确地定制外设组合。I2C 的运行频率可以高达 3.4 MHz(PMBus 和 SMBus 也同样支持)。SAM L22 还支持 ISO7816 接口。
• DMA — SAM L 系列以支持内存与外设数据传输的 16 通道 DMA 控制器为特点。 全速 USB — SAM L21 既支持 USB 嵌入式主机又支持 USB 设备模式,而 SAM L22 则支持全速 USB 设备模式。使用内部 RC 振荡器时,在设备模式下支持全速 USB,从而降低了 BOM 成本和设计复杂性。
Atmel QTouch® 外设触摸控制器 — 可为按钮、滑条、滑轮和近距离感应提供内置的硬件支持,并支持互电容式和自电容式触摸,而无需外部元件。它具有卓越的灵敏度、耐噪性以及自校准功能,任何用户都可以调整余量。
• 可扩展性 — 闪存的密度范围是 32 KB 到 256 KB,SRAM 最高为 40 kB,可以选择 32 至 100 管脚的封装。

围观 432



引言:物联网是雾计算,需推动公开参考架构如IP的发展以加快部署。

物联网既是IC业倾心向往的市场,其碎片化应用亦让IC厂商“左右为难”。 “物联网是诸多垂直市场的集合,这些市场通过连接节点到云以提供服务。” ARM 处理器部门市场营销总监Ian Smythe认为,“物联网不是一个‘一刀切’的市场——分布在由末端节点到云的计算、存储和控制取决于特定的应用,这通常被称为雾计算(Fog Computing),也就是特定任务所需的资源能够在被需要的地方找到,而不是将其放在远离物联网终端节点的中心位置,这需推动公开参考架构如IP的发展以加快雾技术的部署。”问题来了,这种雾计算的潮流,为IP带来什么样的觉醒?

▼IP发展分化为三大方向

“物联网IP依赖于特定的应用——简单物联网节点需要非常低功耗的处理IP,通常结合模拟和MEMS功能,而更复杂的节点需要一个支持更丰富OS、图像处理和显示的IP。” Ian Smythe认为。

国内芯片设计服务公司某技术负责人也表示,IP一贯的发展方式是把专业算法通过IC的方式来实现,物联网不同应用场景会影响IP及规格的定义,比如用电池供电和用电网供电对IP的功耗要求就是天上地下。

他还提到,IP从概念到真正实现,通常大概经过算法原型设计、算法优化、C-Model设计、Verilog实现、RTL实现和优化、布线综合、Netlist交付等环节。虽然算法原型和算法优化最关键,但是每个环节都很重要,比如RDA起家就是因为RF芯片布线做到了极致。

由于物联网涵盖太广,除去目前在手机和监控市场上已有的这些IP,未来要求更高的功耗控制IP、电磁波到能量转换的IP、各种传输协议的IP等等有很多空间,MCU也应会再次迎来春天。物联网新的市场总会带来新的格局,这是实现赶超的机会,研发适合市场需求的足够好的IP是实现赶超的方法。

在这一过程中,也逐渐分化出三个方面值得关注。“一是物联网市场将有效推动定制SoC的增长,从而将导致对IP需求的增长,典型的是将模拟IP和数字IP结合。二是催生专业的IP需求。如可穿戴设备和物联网节点最初采用为智能手机设计的芯片组,而目前可看到诸多专门为可穿戴设计的芯片组。三是物联网的安全需求对IP的安全性提出新需求。”Ian Smythe分析说。

而IP仅是提供了一个入口,更重要的是搭建IP生态链。“物联网构建于一个强大的生态系统之上,应提供一系列基于IP的广泛工具、软件和硅,使开发者能够有广泛的选择来开发出卓越产品。” Ian Smythe表示。

▼安全IP成争战焦点

随着物联网设备中的安全威胁越来越普遍,构置全方位的安全“防线”变得至关重要。新思科技产品市场经理Rich Collins分析认为,目前物联网在网络层、设备层和芯片层都会遭受攻击,而攻击的手段包括网络攻击、软件攻击、硬件攻击。

在芯片层面,更易受到软件和侵入式硬件攻击。Rich Collins指出,就SoC而言,有诸多安全弱点,比如存储器件容易受到恶意应用攻击,ROM容易遭受IP盗用,总线容易受通过外设的软件攻击等等,而目前最难防的就是侧信道攻击,即针对加密电子设备在运行过程中的时间消耗、功率消耗或电磁辐射之类的侧信道信息泄露而对加密设备进行攻击。

为此,新思推出了全新的SEM处理器,其在ARC家族SE的基础上进行了有效的安全优化,对林林总总的攻击可谓“层层设防、各个击破”。

“SEM处理器添加了统一指令时序和时序/能耗随机化功能的侧信道抵御力,从而能有效地防止侧信道攻击;增强的内存保护单元和SecureShield技术简化了可信执行环境的开发; 带有内嵌指令/数据加密和地址加扰的防篡改流水线以及数据完整性,可检查能够抵御系统攻击和IP盗用;集成的监视器计时器可检测包括篡改在内的系统故障等。” Rich Collins详细说,“虽然增加了诸多安全功能,但ARC SEM的功耗仅增加了不到一成,客户可针对物联网应用开发更加安全的SoC。”

虽然市场上的安全IP都有展所长,诸如ARM的TrustZone技术、Imagination的OmniShield技术等均在发挥用武之地。但Rich Collins表示,目前TrustZone只支持ARM的Cortex-A系列IP,但针对广大嵌入式应用的Cortex-M核并未集成该技术,因此ARC SEM可弥补这一市场空白。

Rich Collins还指出,SEM处理器既可成主控制器,也可成加强安全性能的协处理器。“ARC EM处理器年出货量已超过15亿片,Intel等都是新思的重要客户,相信具有最高安全级别的ARC SEM处理器将在IoT市场大放异彩。”Rich Collins强调。

▼异构计算开启破冰之旅

伴随着人工智能、大数据、云计算的高速发展,对SoC提出了更高的要求,异构计算开始大行其道。然而,多数SoC虽在物理上实现了单芯片多核集成,但涉及多套工具和复杂流程,开发不易,优化更难,因而整体性能不高、功耗难降。

为破解这一难题,Imagination最新推出了一款 64 位、多线程、多核、多集群的I6500 CPU,可在集群中连续部署内部异构和外部异构。

MIPS处理器IP执行副总裁Jim Nicholas表示,I6500与上一代I6400的差异在于同步异构技术,它可实现64个集群,每一个集群可支持6核,而每核可配置为单线、双线或是四线程,最多可支持1536个处理单元。这些核和线程的配置是完全独立的,同时Imagination提供工具包和管理单元来确保核之间的通讯管理。

Imagination首席执行官Andrew Heath强调,“对于内部异构,在单一集群中,设计人员能够通过不同的线程组合、不同缓存容量、不同频率甚至电压来配置每个CPU ,实现最优化的功耗;对于外部异构,I6500拥有ACE接口的最新MIPS一致性管理器,能与其他常用 ACE一致性架构解决方案相连,实现出色的系统效率;对于并行多线程,以广泛验证的双发射执行设计为基础,提供更高的效率。I6500 还具有 MIPS I6400 核率先支持的实时硬件虚拟化技术;在安全方面,I6500支持 OmniShield 技术,为安全奠定基础。”

“它是业界多线程是唯一一个可以授权的技术。依据这一技术,可显著地提升性能至80%。与ARM不同的是,ARM只能针对核与集群两方面进行调节,而Imagination可通过将线程、核、集群三者结合来调整功耗跟性能的平衡,更具灵活性和定制性,对物联网和服务器等应用的SoC开发而言优势显著。” Jim Nicholas补充说。

在MIPS领域的发力是Imagination重整之后的战略之一,目前其战略规划已十分具象。Andrew Heath表示,Imagination的三大核心IP专注于MIPS将不断提升异构能力,PowerVR将拓展在图像处理、虚拟现实、人工智能等方面的应用,Ensigma将侧重物联网应用及与WiFi和蓝牙的结合,强力聚焦于移动通讯、汽车、物联网、消费类电子、网络、AR/VR六大领域。

Andrew Heath同时强调,中国是非常重要的市场,与Imagination未来的发展息息相关。Imagination将通过在中国扩充团队、扩展与各大高校的合作、加强与中国芯片厂商如炬芯等合作,助力搭建健康的生态系统。Imagination深知并不断践行“合作伙伴成功Imagination才真正成功”之道。

转载自:智慧产品圈

围观 338

多线程编程是现代软件技术中很重要的一个环节。要弄懂多线程,这就要牵涉到多进程?当然,要了解到多进程,就要涉及到操作系统。不过大家也不要紧张,听我慢慢道来。这其中的环节其实并不复杂。

(1)单CPU下的多线程
在没有出现多核CPU之前,我们的计算资源是唯一的。如果系统中有多个任务要处理的话,那么就需要按照某种规则依次调度这些任务进行处理。什么规则呢?可以是一些简单的调度方法,比如说

1)按照优先级调度
2)按照FIFO调度
3)按照时间片调度等等

当然,除了CPU资源之外,系统中还有一些其他的资源需要共享,比如说内存、文件、端口、socket等。既然前面说到系统中的资源是有限的,那么获取这些资源的最小单元体是什么呢,其实就是进程。

举个例子来说,在Linux上面每一个享有资源的个体称为task_struct,实际上和我们说的进程是一样的。我们可以看看task_struct(linux 0.11代码)都包括哪些内容,

1

每一个task都有自己的pid,在系统中资源的分配都是按照pid进行处理的。这也就说明,进程确实是资源分配的主体。

这时候,可能有朋友会问了,既然task_struct是资源分配的主体,那为什么又出来thread?为什么系统调度的时候是按照thread调度,而不是按照进程调度呢?原因其实很简单,进程之间的数据沟通非常麻烦,因为我们之所以把这些进程分开,不正是希望它们之间不要相互影响嘛。

假设是两个进程之间数据传输,那么需要如果需要对共享数据进行访问需要哪些步骤呢

1)创建共享内存
2)访问共享内存->系统调用->读取数据
3)写入共享内存->系统调用->写入数据

要是写个代码,大家可能就更明白了,

2

上面的代码是一个创建子进程的代码,我们发现打印的value数值还是10。尽管中间创建了子进程,修改了value的数值,但是我们发现打印下来的数值并没有发生改变,这就说明了不同的进程之间内存上是不共享的。

那么,如果修改成thread有什么好处呢?其实最大的好处就是每个thread除了享受单独cpu调度的机会,还能共享每个进程下的所有资源。要是调度的单位是进程,那么每个进程只能干一件事情,但是进程之间是需要相互交互数据的,而进程之间的数据都需要系统调用才能应用,这在无形之中就降低了数据的处理效率。

(2)多核CPU下的多线程
没有出现多核之前,我们的CPU实际上是按照某种规则对线程依次进行调度的。在某一个特定的时刻,CPU执行的还是某一个特定的线程。然而,现在有了多核CPU,一切变得不一样了,因为在某一时刻很有可能确实是n个任务在n个核上运行。我们可以编写一个简单的open mp测试一下,如果还是一个核,运行的时间就应该是一样的。

3

(3)多线程编程
为什么要多线程编程呢?这其中的原因很多,我们可以举例解决

1)有的是为了提高运行的速度,比如多核cpu下的多线程

2)有的是为了提高资源的利用率,比如在网络环境下下载资源时,时延常常很高,我们可以通过不同的thread从不同的地方获取资源,这样可以提高效率

3)有的为了提供更好的服务,比如说是服务器

4)其他需要多线程编程的地方等等

来源:网络

围观 397

这个题目是我临时想的,不知道是否准确,一直想写一个类似的东西,希望能够引起童鞋们关注硬件并喜欢上硬件。

我是文科出生,研究生阶段才转向计算机,中间有很长一段时间都只做软件理论相关研究和一些具体的软件项目,包括编译器、电力系统监控器、软件测试工具研发等;直到2009年,才开始陆陆续续接触一些硬件项目,说是硬件项目,其实主要是一些嵌入式的项目,如世界杯前做的3G转Wifi和自己玩的一些小车和传感器等。

在做嵌入式项目之前,压根就没接触过硬件方面的开发知识,难度可想而知,什么叫编码器、什么叫译码器、怎么做分频、怎么做倍频、怎么做A/D转换、D/A等等,一系列的问题迎面而来。为了完成项目,只能硬着头皮上,从最基础的数字逻辑开始看起,从二进制、卡诺图入手,逐渐深入到组合电路和时序电路,再结合一本叫做《计算机组成与设计-硬件/软件接口》,才逐渐深入明白我们做的编译器后端的具体工作原理,在此基础上对软件的各种性能问题有了更深刻的认识。

组合电路和时序电路是计算机原理的基础课,组合电路描述的是单一的函数功能,函数输出只与当前的函数输入相关;时序电路则引入了时间维度,时序电路在通电的情况下,能够保持状态,电路的输出不仅与当前的输入有关,而且与前一时刻的电路状态相关,如我们个人PC中的内存和CPU中的寄存器,均为时序电路。

说了这么多,我们学习的组合电路和时序电路在计算机中又是怎么一回事呢?为了便于理解,下面以一个大家都能接受的C语言程序开始,从上层向下层开始解释。

void main(){
int a = 3, b = 5;
int sum = a + b;
}

这个例子大家都能明白,main函数要做的事情就是实现两个数的加法操作。这是我们人类的思维方式,但是计算机并不认识,如何让计算机理解呢?于是,我们需要将上面这个程序翻译成机器能理解的模样,这时候就需要借助编译器(如常见的gcc、msc等)将上面的程序翻译成MIPS指令(不同的CPU有不同的指令集,包括X86指令集、MIPS指令集、Sparc指令集等,我们在这里用MIPS指令集,咱们的龙芯也是采用MIPS指令集),如下所示:

#下面的每条汇编代码对应一个二进制
addi $t0, 0, 3 # a = 0+3, a保存在$t0寄存器中, 对应的二进制代码为:0010 00** **** **** **** **** **** ****(这里的星号*表示二进制,这里暂时不关心)
addi $t1, 0, 5 # b = 0+5, b保存在$t1寄存器中
addi $t2, $t1, $t0 # sum = a + b, sum保存在$t2寄存器中

到这里,大家一定还在疑惑,不是说要翻译成二进制代码吗?怎么是MIPS汇编语言?对,就是汇编语言,这个汇编语言中的每一条指令就对应一条二进制代码,汇编的方式更容易让人理解。

现在我们得到了计算机可以理解的MIPS指令(可以想象成可执行程序)了,接下来的问题是如何执行MIPS指令。

要执行程序,首先必须将可执行程序文件(从外设)加载到内存。可执行文件加载到内存时,操作系统会为每个可执行程序在内存中分配四个区:

1 代码区。也就是前面的到的汇编代码所对应的二进制码
2 全局数据区。全局变量,静态变量放在这个区
3 堆区。表示在程序执行过程中,动态申请的空间在这个区,如C语言中的malloc, free操作均是针对此区中的对象执行申请或释放操作
4 栈区。函数运行时,局部变量的保存区域。
我们重点关注代码区和栈区,初始时,其分布如下图所示:

组合电路、时序电路在计算机课程中的地位

代码区-1.png

其中PC(Program Counter)是程序计数器(是CPU中的一个寄存器,具有数据存储功能),即用来指示下一个即将执行的指令的地址,本例中,进入main函数后,即将执行的第一条指令是a = 3,其地址为:0X FF FF FF 00, 因此PC指向其对应的汇编代码的地址。

CPU根据PC的的值,从指定地址0X FF FF FF 00处获取指令,然后解析指令,并执行指令(即执行a=3)。

当a = 0执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 04,即b = 5的指令的地址。此时,栈区的状态为:

组合电路、时序电路在计算机课程中的地位

栈区-1.png

接着,CPU根据PC的的值,从指定地址0X FF FF FF 04处获取指令,然后解析指令,并执行指令(即执行b=5)。当b=5执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 08,即sum=a+b的指令的地址。此时,栈区的状态为:

组合电路、时序电路在计算机课程中的地位

栈区-2.png

然后,CPU根据PC的的值,从指定地址0X FF FF FF 08处获取指令,然后解析指令,并执行指令(即执行sum=a+b)。当sum=a+b执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 12(因为,指令已经执行完毕,这里应该提示要从main函数返回)。此时,栈区的状态为:

组合电路、时序电路在计算机课程中的地位

栈区-3.png

至此为止,main函数内部的流程基本上陈述完了(关于函数间调用,相对复杂,计算机组成中会详细讲解),但如何实现这些步骤呢,其中的关键问题包括如下:

问题:
1、知道内存地址,如何定位到那个地址???答案:地址译码器
2、获取到a=3对应的指令后,如何知道是做a=0+3的操作???答案:解析指令,指令译码器
3、PC寄存器如何保存值?如何做加4操作?答案:计数器(寄存器讲解)

作者:CodingTech
来源:
简书

围观 355

页面

订阅 RSS - CPU