超标量处理器设计——第九章_执行


参考《超标量处理器》姚永斌著

超标量处理器设计——第九章_执行

9.1 概述

  • 每个FU都有一个1-M仲裁器, 每个仲裁器和物理寄存器堆的读端口一一对应

9.2 FU类型

9.2.1 ALU

  • Arithmetic and Logic Unit

  • MIPS中如果加减法发生溢出, 需要产生异常

  • ARM中, 直接定义了状态寄存器CPSR:

    • ARM中定义了四种加减法操作:

      1. 不带进位加: X + Y = X+Y+0
      2. 带进位加: X + Y + Cin
      3. 不带借位减: X-Y = X + (~Y + 1) , 实际就是补码运算
      4. 带借位减: X-Y-1 = X + (~Y+1)-1 = X + (~Y)
  • 一些ALU可能还会包含简单的乘除法, 而这些操作周期数较多,对bypass功能引入了一些复杂度:

  • MIPS和ARM都集成了CLZ (Counting Leading Zero),用来判断32位寄存器从高位开始连续0的个数, 用来做优先级判断:

  • 一些处理器使用单独的乘法器FU获得高并行度, 还会自带乘累加功能(MADD)

  • 一些处理器为了节省面积,将整数转换成浮点数,放入浮点FU中计算乘法

9.2.2 AGU

  • Address Generate Unit
  • Load/Store携带的存储器地址通过AGU处理
  • 普通流水线处理器中一般这个工作交给ALU处理, 但是超标量处理器为了并行执行,单独使用一个FU来计算地址

9.2.3 BRU

  • Branch Unit
  • 负责分支指令: branch, jump, Call, Return等
  • 将指令携带的目标地址计算出来,根据条件决定是否使用
  • 还存在分支预测正确性检查
条件码
  • ARM和PowerPC采用与MIPS不同的分支方法, 即条件码:

  • 条件码的优点:

    • 条件码降低分支指令使用频率, 对超标量处理器来说能获得更好的性能.
  • 缺点:

    • 条件码占据了指令编码的一部分,导致可分配给寄存器的部分变少了,例如ARM加入了4位条件码后, 实际可用的指令编码空间就只有32-4=28位了. 简介导致其只支持16个通用寄存器.

    • 此外,条件码会使得所有指令都进入流水线, 会存在大量无效指令, 效率不高

    • 另外, 条件码的可能导致寄存器重命名时的额外麻烦:

    • 该图中,如果SUBNE不执行, 那么ADD就会使用错误的物理寄存器P7, 而实际上应该用的是P6

    • x86对该问题的一个解决方案是硬件插入额外的指令:

    • uOP指令根据两个条件执行的结果对物理寄存器进行选择, 但是必须保证条件执行指令成对出现

分支正确性检查
  • 在流水线的取指阶段会将预测跳转的分支指令保存在一个缓存中, 称为分支缓存(branch stack)
  • BRU的到一条分支的结果时, 会在分支缓存中进行查找, 有四种情况:
    1. BRU的结果是跳转, 且分支缓存中能找到他, 跳转地址也相同 ---- 预测正确
    2. BRU的结果是跳转, 但是分支缓存中找不到他 ---- 预测失败
    3. BRU的结果是不跳转, 且分支缓存中找不到他 ---- 预测正确
    4. BRU的结果是不跳转, 但是分支缓存中能找到他 ---- 预测失败
  • 如果预测正确, 释放该分支占用的资源, 如checkpoint或分支缓存

9.3 旁路网络

  • 目的: 为了使存在相关性的指令能背靠背执行

  • 源操作数从物理寄存器读出,还需要经过一段时间才能到FU输入口, 这些周期称为Source Drive阶段

  • FU将一条指令结果计算出来后, 还需要经过复杂的旁路网络才能到达所以FU的输入(或PRF输入), 这个阶段称为Result Drive阶段.

9.3.1 简单设计的旁路网络

  • 当一个FU中有多个功能, 例如ALU可以计算移位,也可以计算加减法. 对这样的FU需要用多路选择器, 从不同的计算电路中选择一个结果放到旁路网络, 这种做法称为 bypass sharing

  • 如果一个FU中所有计算单元周期数不等, 可能会导致某一个周期FU中的两个计算单元竞争旁路网络的情况:

  • 一种解决方法是借鉴推测唤醒的做法, 一条指令在到达FU之前,先检查FU是否可以被自己使用. 例如上个周期FU执行了latency = 3的指令, 那么本周期就不能执行latency=2的指令了.

  • 具体实现:

    • 用一个两bit的控制寄存器, 每周期会逻辑右移一位.

    • 当本周期被仲裁电路选中的是latency=3的指令, 就在下一周期将控制寄存器设置为2’b10. 表示下周期不允许latency=2的指令参与仲裁. 下下周期控制寄存器变为2’b01, 表示下下周期不允许latency =1的指令参与仲裁

    • 假设本周期仲裁电路选中latency=3的指令, 下周期仍然选中latency=3的指令, 此时的处理是将两次的控制寄存器相或:

9.3.2 复杂设计的旁路网络

  • 指令B可以在Execute阶段从A的Result drive阶段获得操作数

  • 指令C可以在Source drive阶段从A的Result drive阶段获得操作数, 或者C也可以在Execute阶段, 从A的Write Back阶段获得操作数

  • 指令D可以在Source drive 阶段从A的write back阶段或的操作数

  • 指令E在流水线RF read阶段读取物理寄存器堆(PRF)时, 可以的到指令A的结果, 所以其不需要从旁路网络获得操作数

  • 旁路网络会使得流水线变得很复杂:

    • 可以发现, 在上述流水线中, 当两条指令间隔的指令超过两条时, 就不需要通过旁路网络或的操作数了

    • 增大流水线级数会导致更复杂的旁路网络

    • 不需要在所有FU之间都设置旁路网络, 例如AGU会用到ALU结果, 但是ALU不会用到AGU的结果

9.4 操作数的选择

  • FU 的输入端需要从物理寄存器的输出或所有旁路网络中进行选择.

  • 一个物理寄存器在生命周期内会有多种状态, 他可能被写到PRF, 还可能需要在指令顺利离开流水线时写到ARF中. 这些信息都可以保存在一个表格内,称为 ScoreBoard

  • FU# : 从旁路网络取出某个物理寄存器时,需要知道来自哪个FU, Scoreboard的FU#记录了该信息. 当一条指令被仲裁器选中时, 如果指令有目的寄存器, 那么就将该指令在哪个FU中执行的信息写到该表中

  • R : 表示该寄存器已经被FU计算完毕, 并写到了PRF中, 后续指令如果要使用该寄存器器, 可以直接从PRF中读取. 如果该位为1, 就不需要关注FU#信息了.

  • 在流水线中加入该表格:

    • 会影响Select阶段(写入FU#)和Write Back阶段(更新R)

    • 上图中指令C可以在EX阶段读取Scoreboard, 因为A已经将结果写到PRF了, 所以此时C读取SB后知道应该去PRF中取操作数, 但是这样会导致EX阶段延时变长. 对应的电路如下:

    • C指令其实在RF read阶段就开始读取SB, 打一拍后进入EX:

      • 这种方法能缓解EX延时过长的问题, 但是会导致C读SB时, R位还没有置1, C会错误的认为自己应该从旁路网络去获得操作数

      • 可以简单地打个补丁, 也就是如果发现写入SB时(更新R)与读取SB时(RF阶段读取FU#)所用的物理寄存器相同(一个地址), 就将EX的多路选择器切到PRF上, 而不是实际读出的FU#

  • 如果处理器每周期可以执行N条指令, 那就需要SB有2N个读端口, 而SB需要分两次写如FU#和R, 所以又需要2N个写端口!

  • 除了使用SB, 另一个方案是使用比较器产生MUX的控制信号:

    • FU在将计算结果广播到bus上时, 同时也将该指令的目的寄存器编号也一起广播
    • 每条指令在从旁路网络选择操作数的两个周期内, 也就是Source Drive和Ex阶段将源操作寄存器编号和FU送来的目的寄存器编号进行比较, 如果相等, 说明此时需要从旁路网络获得操作数, 否则就是从PRF获取.
    • 代价是更大的面积和功耗, 但是很简单.

9.5 Cluster

  • Cluster是一种结构实现的思路, 例如将浮点FU和整数FU的旁路网络分开, 或者将一个IQ分为多个独立的IQ

9.5.1 Cluster IQ

  • 集中式的IQ往往需要更多的读写端口和更大的容量, 导致面积和延时都很大

  • 可以使用Cluster的结构, 将集中IQ拆分成多个小的分布式IQ, 每个IQ只对应一个或几个仲裁电路和FU

  • 带来的优点:

    1. 可以减少每个分布式IQ的端口个数
    2. 每个分布式IQ的仲裁电路只需要负责很小一部分的指令, 可以加快仲裁电路的速度
    3. 分布式IQ的容量较小, 其中的指令被唤醒的速度也较快
  • 缺点:

    1. 被仲裁电路选中的指令对其他IQ中的指令进行唤醒时, 走线会更长, 延迟会增大, 甚至需要增加一级流水, 此时原来有相关性的两条指令就不能背靠背了, 会引入一个bubble.
  • 解决办法

    • 例如:下图中的五条指令,只需要一个周期就可以从FU中得到结果,相关性如图:
    • 正常情况下: 第一个周期A,B被仲裁选中, 第二周期CD选中,第三周期E选中

    • 采用了分布式的IQ之后,假设跨越Cluster唤醒需要消耗一个周期,此时有两种情况:

      1. ABE在一个cluster,指令CD在另一个Cluster中。AB在被选中后,要等一个周期才能唤醒C和D, D被选中后也要等一个周期才能唤醒E:

      2. AC分到同一个Cluster中, BDE分到另一个Cluster中:

      • 可见执行效率跟在不在一个Cluster有关,需要仔细规划分配算法
  • 对于非数据捕捉结构的超标量处理器, 指令在被仲裁电路选中后会先读取PRF, 因此需要PRF支持多个读端口,可以对寄存器堆也使用Cluster结构:

    • 这种做法可以减少读端口,但是无法减少写端口

    • SRAM的面积近似跟端口个数的平方成正比,因为布线资源随端口数平方增长,所以减少读端口仍然可以减少面积。

9.5.2 Cluster Bypass

  • 对旁路网络使用Cluster之后, 旁路网络只分布在每个Cluster内部:

  • 因为旁路网络大幅度简化了,所以可以去掉Source Drive和Result Drive两个阶段,节省了两级流水,这一同一个Cluster的指令仍然可以背靠背,不同Cluster的指令只需要间隔1个周期:

  • 将一个FU的结果送到其他Cluster的FU输入往往延时较大, 所以可能需要为此加一级流水:

  • 跨Cluster进行唤醒会引入一个周期延迟, 跨FU的旁路网络也需要一个周期延时,但是实际上这两级延时不是叠加的,而是合并的:

9.6 存储器指令的加速

9.6.1 Memory Disambiguation

  • LOAD, STORE指令之间也有相关性:

  • 一般store指令都是顺序执行的,这样可以避免WAW相关性,但load可以有不同的实现方式:

    1. 完全的顺序执行

      • 最保守,不能将load提前执行,导致所有相关指令执行都偏晚
    2. 部分的乱序执行

      • 每当一条store指令的地址被计算出来后,这条store和它后面的store指令之间的所有load都可以乱序

      • 两条stroe指令之间的load可以乱序, 避免了WAR相关性

      • 当一条store被仲裁电路选中,位于其后的load就可以参与仲裁了,且这些load可以乱序地被选中

      • 但是被选中的load还是需要和前面所有已经执行的store指令携带的地址进行比较,以判断RAW相关性

      • 需要一个缓存来保存被仲裁电路选中但还没顺利离开流水线的store指令,该缓存称为Store Buffer

      • 如果load在store buffer中发现了地址相等的store指令, 说明发现了RAW相关性,直接从该缓存中就可以得到load所需的数据

      • store就像一扇门, 当其被仲裁电路选中之后,就可以开门,放行之后的load指令进入仲裁器:

      • 实际上,这种方式只保证store指令是顺序的,例如A先执行,A唤醒了C,但是B,D还没进入仲裁;此时指令E又被仲裁电路选中,它使得F和G也有资格参与仲裁;因此这时B,D,F,G都可以被仲裁电路乱序选中

      • 新的问题:E指令先于B,D被仲裁选中时,指令B和D被选中时查找Store buffer会有两条store指令,但是B,D与E实际没有相关性,因此需要鉴别Store Buffer中哪些store在本条load的前面,哪些在后面。有如下方法:

        1. 用PC值标记先后顺序。实际不可靠,因为如果store之后有向前跳转的指令,该方法就失效了:

        2. 用ROB编号。ROB记录了指令进入流水线的先后顺序,ROB中的地址可以表示先后。但是实际ROB不止存放load和store,导致这个标号非常稀疏,比较大小时浪费比较器面积

        3. 在解码阶段,为load和store分配一个编号,编号宽度根据流水线最多支持的load/store来决定

      • 这些记录load,store顺序的标号固然可以解决问题,但是带来了复杂度,实际上可以要求B,C,D都被仲裁电路选中之后,才能让E进入仲裁。当然代价是牺牲性能,因为如果store指令A发生缺失,E就不能被选中:

      1. 完全的乱序执行
        • store仍然是顺序执行,但load将不再受限于它前面的store指令,只要其操作数准备好,可以立即参与仲裁
        • load的仲裁,可以按照oldest-first的策略,乱序进入仲裁器(这里的乱序指的是不需要关store在前还是在后)
        • 可以这么做是基于一个观察:RISC处理器中,ARF的数量实际是较多的,很多变量可以直接放到寄存器中。程序中store/load指令间的RAW相关性不会很多,可以通过提前执行load来尽快唤醒更多指令,以获得更大的并行性
        • CISC处理器中由于可用的通用寄存器较少,需要经常跟mem进行通信。Store/load存在RAW的情况就较多:
          • Store/Load指令违例: 如上图, 本来在Store下方的Load提前到store之前执行, 如果r5=r9, 将导致违例

          • Load/Store相关性预测: 预测load指令和前面的store指令存在RAW相关性而不能被提前执行

          • 硬件处理store/load违例不多见, 通常在比较新的指令集会考虑,例如VLIW处理器领域的intel Itanium:

            • 对一条提前到store指令之前的load指令进行标记:

            • load.a就是做了标记的指令, 该指令除了load数据外, 还会将load计算出来的地址放到一个表格ALAT(Advanced Load Address Table)中:

            • Size表示存储word, halfword 或byte

            • 没当store指令计算出来地址,都会据此来查找ALAT, 因此需要Address表项支持内容寻址功能(CAM)

            • 如果发现携带地址想他的load指令,会将该load踢出ALAT, 让store指令占据这个位置, 表示发现了load指令违例

            • load指令被提前调度到store之前时, 会在调度后的load加上.a标记, 同时也会在load原来所在的位置加上一条新的指令 load.c

            • load.c指令会检查ALAT,如果发现自己不在ALAT中(被store踢出), 表示发生了违例, 需要进行修复. 修复通常是一段fixup code固定代码

            • 顺带提一句,虽然intel Itanium开发了新的指令集,但是失败了…

9.6.2 非阻塞Cache

  • 在RISC中, 只有像load和store这样的访存指令才可以访问mem
  • 对于load指令, 如果发生D-Cache缺失,需要找到一个Cache line放入内存中的数据, 如果Cache line是脏的,还要把line的数据块先写回物理内存
  • 对Store指令来说, 如果他的地址不在D-Cache中,那么对于write back+ write allocate类型的Cache来说, 要先从内存中找到地址对应的数据块, 将其取出, 和store的数据进行合并, 再从D-Cache中按照某种算法找到一个Cache line放入.如果被替换的line是脏的, 那在写入之前还要把这个数据协会内存
  • 如果在某个访存指令处理D-Cache miss期间, 又有新的访存指令发生了miss, 该如何?
    • 一种方法是miss之后, 阻塞其他load store指令, 这种就是阻塞(Blocking)Cache:

    • 性能很低, 因为一般load在数据相关性的顶端

    • 非阻塞(Non-blocking)Cache: 也叫lookup-free Cache, 允许D-Cache miss 的时候继续执行新的访存指令:

    • 需要在scoreboard中将发生D-Cache缺失的load指令的目的寄存器标记为不可获得的状态.

    • 带来的问题: load.store指令的Cache miss处理完的时间可能和原始指令顺序不一样. 例如load1需要从内存中导入数据, load2只需要从L2 Cache中导入

    • 处理器需要将产生D-Cache miss 的load/store指令保存到一个部件中, 该部件就是MSHR(Miss Status/information Holding Register), 也叫做 MAF(Miss Address File):

      • 先了解几个概念:

        1. 首次缺失(Primary Miss): 访问D-Cache时第一次产生的缺失
        2. 再次缺失(Secondary Miss): 发生首次缺失且没有被解决完之前, 后续的访存指令再次访问这个发生缺失的Cache line
      • MSHR中:

        1. V: Valid位, 表示表项是否被占用, 首次缺失发生时, 会占用一个表项, 当Cache line从下级存储器被取回时, 会释放表项, valid清除
        2. Block Address: Cache line中数据块的公共地址. 假设Cache line数据块大小是64byte, 则需要6位来索引. 对于一个32位的物理地址, 其余的26位就是数据块的公共地址. 每次load/store发生缺失时都会在MSHR查找所需数据块是否正在被取回
        3. Issued: 发生首次缺失的访存指令是否开始处理. 因为存储器带宽有限, 所以占用MSHR本体的首次缺失不一定马上被处理, 而是得等到条件满足时才会向下一级存储发出读数据请求.
      • LOAD/STORE Table: 记录首次缺失和再次缺失的访存指令

        1. V: valid位, 表示是否被占用
        2. MSHR entry: 表示一条发生缺失的访存指令属于MSHR本体中的哪个表项. 由于产生miss的很多访存指令可能对应同一个Cache line, 他们只占用一个MSHR表项, 但是需要占用LOAD/STORE TABLE中的不同表项. 如此, 当缺失数据块从下级存储取回时, 可以根据block address定位到MSHR中的位置, 并据此在LOAD/STORE TABLE中找到哪些指令属于该cache line
        3. Dest.register:
          • 对load指令来说, 这部分记录目的寄存器(物理)编号, 当数据块取回时, 就可以将对应数据送到这部分记录的寄存器中.
          • 对store指令来说, 这部分记录store指令在store buffer 中的编号. 当store指令发生缺失, 它的数据不会立即写到cache ,而是停留在store buffer. 当下级存储器取回数据后, 才将要存储的数据合并到数据块, 再将合并后的数据写到D-Cache, 此时才能从Store Buffer中释放该store占据的空间. 所以LOAD/STORE TABLE中的这个表项一是为了找到store指令携带的数据, 二是释放store占据的store buffer空间.
        4. Type: 记录访存指令的类型., 例如Load Word, Load Half word等
        5. Offset: 访存指令所需数据在数据块中的Byte偏移
    • MSHR和LOAD/STORE TABLE的配合可以支持非阻塞Cache的操作方式:

      1. 当访存指令发生Miss时, 查找MSHR, 将发生Miss的地址与MSHR的所有block address进行比较.
      2. 如果发现想等的表项存在, 表示缺失数据块正在被处理,这次是再次缺失, 此时只需要将这条访存指令写到LOAD/STORE TABLE即可
      3. 如果没有发现想等表项, 表示此时是首次缺失, 需要将该指令写到MSHR和LOAD/STORE TABLE
    • 如果MSHR或LOAD/STORE TABLE任意一个满了, 表示不能在处理新的访存指令, 应该让流水线暂停选择新的访存指令

    • MSHR容量不会很大, 多为4-8个 ^737697

    • 非阻塞Cache虽然性能较高,但是会占用较大的面积:

      • 以8个表项MSHR和16个表项的LOAD/STORE Table为例:
    • 为了解决MSHR占用面积大的问题, in-Cache MSHR的方法被提出:

      • D-Cache miss时, 从下一级存储器中提取数据, 此时D-Cache中的这一个cache line是空闲的, 没起任何作用.
      • 可以将这个cache line作为存储MSHR的地方, 不过需要在cache line中再加一位, 称为transient bit, 表示这个Cache line中的数据正在从下一级存储器中被取回
      • 当Cache line处于该模式, 其tag用来存储block address, 其他部分保持MSHR信息
    • in-cache的缺点是:

      1. Cache的读端口宽度一般远小于Cache line中数据块大小. 例如每周期可以执行4条指令的处理器, D-Cache的读端口一般小于4个, 每个读端口宽度都是32位, 则读带宽最多就4*4=16byte, 远小于Cache line中数据块大小, 导致需要多个周期才能从Cache line中将MSHR的信息读出来
  • 超标量处理器中, 非阻塞Cache实现会更复杂一些, 由于采用分支预测和乱序执行, 一些引发Cache miss的load/store指令可能处于预测失败的路径上, 因此需要一种机制来选择性地放弃一些正在处理的D-Cache miss:
    1. 如果一条load在分支预测失败的路径上, 则该指令需要从流水线中抹除, 且还需将LOAD/STORE Table中相应表项删除
    2. 如果某个发生缺失的数据块正在从下一级取回, 此时发现访问该数据块的所有load/store都处在分支预测失败的路径上, 那么这个数据块不应该被写入D-Cache

9.6.3 关键字优先

  • 当发生D-Cache缺失时, 要将该指令所要的整数个数据块从下级存储取出, 如果考虑预取(prefetching), 还要将相邻的下个数据块也取出:

  • 如果等到所有数据都写到D-Cache之后才将所需要的数据送给CPU, 这会让CPU等待一段时间. 可以对D-Cache进行改造来加快执行速度:

  • 关键字优先(Critical Word First): 如果访存指令需要的数据位于数据块中的第6个字, 则此时可使下一级存储器的读取从第6个字开始, 读到数据块结束后,再回过来读前面0-5个字. 这样CPU可以在第6个字读出后就继续执行. 代价是下级存储器需要为支持这样的特性增加硬件逻辑.

9.6.4 提前开始

  • 关键字优先需要在下级存储中增加额外的硬件支持, 如果不想付出这些成本, 可以采用 提前开始(Early Restart) 的方法:

  • 提前开始的思路是: 第六个字读出后, CPU开始继续执行

  • 与关键字优先的区别是, 这种方法不会改变数据读取的顺序

9.6.5 I-Cache的处理

  • 目前位置的非阻塞Cache, 关键字优先, 提前开始三种方法, 都可以应用到D-Cache, 也可以应用到I-Cache

  • 由于超标量处理器一般都有分支预测, 会根据当前指令地址对下一条指令的地址进行预测. 如果某次读取I-Cache时发生缺失, 并且预测器预测这条指令正好是分支跳转指令, 则大概率会引发两次miss, 因为预测跳转的分支所用的指令大概率不在I-Cache中:

  • 因此I-Cache也可使用非阻塞结构:

  • I-Cache不需要使用太大的MSHR容量, 有时用1个MSHR表项就够了(MIPS R10000)

  • I-Cache使用这些方法与D-Cache的区别是, I-Cache需要保证指令的原始顺序, 即使后面的指令先被取出, 也要等待前面的指令取出

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love小酒窝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值