jjzjj

【蜂鸟E203内核解析】Chap.4 累加运算NICE协处理器的设计

Jie_MSD 2023-04-20 原文

【蜂鸟E203内核解析】Chap.4 累加运算NICE协处理器的设计


前言:本文均为作者原创,内容均来自本人的毕业设计。 未经授权严禁转载、使用。里面的插图和表格均为作者本人制作,如需转载请联系我并标注引用参考。分享仅供大家学习和交流。

1. 累加运算协处理器的设计

  NICE协处理器的调用需要创建用户自定义RISC-V的指令,NICE 支持自定义硬件联合单元的集成,从而提高特定领域的性能,同时降低功耗[6]。
  本设计开发了一个加法运算的协处理器用于加速累加运算操作,其中利用了DDR3数据存储器作为数据缓冲区(详见本论文4.1),将所需进行累加操作的三个数据输入到DDR3内部进行存储,利用NICE协处理器操作存储器提取所需数据到协处理器内部,处理后的数据通过rd寄存器输出,如图4-9所示。由于协处理器的运行是独立于处理器的内核,故可以独立于主处理器进行运算操作,可以减少运行的指令并减少流水线处理累加运算的时钟周期

图4-9 累加运算协处理器

2. 累加运算协处理器的调用

  调用NICE接口有4个通道,请求通道、内存请求通道、响应通道、和内存响应通道。请求通道:主处理器在流水线的EXU级时,将指令的编码信息和源操作数传输到协处理器。反馈通道:协处理器告诉主处理器其已完成了该指令,并将结果反馈到主处理器。存储器请求通道:协处理器向主处理器发起存储器读写请求。存储器反馈通道:主处理器向协处理器写回存储器读写结果。各个通道信号说明如表4-2所示。

表4-2 每个通道的信号的详细说明
通道方向宽度信号名描述
请求通道Output1nice_req_valid主处理器发送指令请求信号给协处理器
Input1nice_req_ready协处理器返回指令接收信号到主处理器
Output32nice_req_instr自定义指令的32位完整编码
Output32nice_req_rs1源寄存器 1 的值
Output32nice_req_rs2源寄存器 2 的值
反馈通道Input1nice_rsp_valid协处理器发送反馈请求信号到主处理器
Output1nice_rsp_ready主处理器返回反馈接收信号给协处理器
Input32nice_rsp_data返回指令的执行结果
Input1nice_rsp_err返回该指令的错误标志
存储器请求通道Input1nice_icb_cmd_valid协处理器发送存储器读写的请求信号到主处理器
Output1nice_icb_cmd_ready主处理器返回存储器读写的接收信号给协处理器
Input32nice_icb_cmd_addr内存访问请求地址
Input1nice_icb_cmd_read内存访问请求的写入或读取(0:写1:阅读)
Input32nice_icb_cmd_wdata写入存储器的数据
Input2nice_icb_cmd_size读写数据的大小(2'b00:字节;2'b01:半字;2'b10:1位;2'b11:保留)
存储器反馈通道Output1nice_icb_rsp_valid主处理器发送存储器读写反馈请求信号到协处理器
Input1nice_icb_rsp_ready协处理器返回存储器读写反馈接收信号给主处理器
Output32nice_icb_rsp_rdata存储器读反馈的数据
Output1nice_icb_rsp_err存储器读写反馈的错误标志
Input1nice_mem_holdup协处理器占用存储器的信号(防止主处理器的后续指令继续访问内存,主处理器和协处理器同时访问内存可能导致竞争性失锁)

  调用协处理器的方法:扩展一个用RTL级代码编写的协处理器,想个办法调用这个独立于流水线的计算单元,调用协处理器应用起来的方法是:在MCU层面,在编译器里编写C语言主函数中包含指定汇编指令的调用,完成驱动的配置。在nuclei-board-labs-master\e203_hbirdv2\common\demo_nice里的insc.h给了调用的示例。

// custom rowsum 
__STATIC_FORCEINLINE int custom_rowsum(int addr)
{
    int rowsum;
    
    asm volatile (
       ".insn r 0x7b, 6, 6, %0, %1, x0"
             :"=r"(rowsum)
             :"r"(addr)
     );
    
    return rowsum; 
}

这里E203内核提供了NICE接口。通过自定义指令调用协处理器的过程如图4-9所示。

图4-9 NICE协处理器的调用过程

  NICE指令的完整执行过程如下:

  1. 主处理器的译码单元提供EXU级译码得到指令的操作码,以判断其是否属于默认的自定义指令组。
  2. 如果该指令属于自定义指令,请根据命令编码中的XS1位继续读取源寄存器。如果XS1和XS2位确定是否需要读取源寄存器,则在EXU级读哪个通用寄存器并取出源操作数。
  3. 主处理器保持数据支持的正确性,如果该指令需要读取源寄存器,并且以前执行的指令依赖于先读取后写入(RAW),则流水线将暂停,直到RAW依赖性被消除。此外,主处理器将根据指令编码中的XD位进行决策,以确定是否需要为预定义的命令将结果写入通用寄存器组,如果需要,则将索引信息存储在主处理器线程控制模块中的目标寄存器中,直到写回完成,以提供数据对后续命令的依赖性判断。
  4. 主处理器在EXU级通过NICE协处理器中接口的请求通道派发给外部的协处理器,派发的信息包括指令的编码信息、两个32位宽的源操作数的值。指令做进一步的译码,请求通道接收指令并依次执行指令。
  5. 协处理器通过反馈通道反馈结果、返回值。
  6. 主处理器提取命令,并将结果写回通用寄存器(如果需要写回)。

3. NICE协处理器里的累加运算模块

  协处理器的功能模块在NICE协处理器内部,如图4-9所示。通过自定义指令调用协处理器后,协处理器的功能模块进行运算。本设计开发了一个累加运算模块用于累加运算,如图4-11所示。输入3个数时,先提取前两个数相加,再将第一次加法的和与第三个数相加,输出3个数的累加值[23]。

图4-11 NICE协处理器里的累加运算模块

4. 自定义指令与NICE协处理器的验证

  输入10、20、30三个数进入协处理器做累加运算,通过Nuclei Studio编译器的调试信息打印所运算的结果,如图4-12所示。为了对比使用协处理器对累加运算的加速效果,设置了一组不使用协处理器的累加对比项(normal),可以发现协处理器可以进行累加运算,运算结果为60。

图4-12 协处理器累加运算结果

  因为关闭调试信息打印输出的情况下处理器可以节约一部分串口输出数据printf函数指令,这里便关闭了调试信息打印输出。可以发现:自定义指令调用NICE协处理器中的累加运算模块进行三个数的累加运算比普通C语言编写的累加运算读写减少了82条指令,同时减少了106个时钟周期,累加运算的性能提升了52%,如图4-13所示。可以预见的是,所涉及的累加运算越多,性能提升越明显

图4-13 协处理器与普通c语言进行累加运算的性能对比

有关【蜂鸟E203内核解析】Chap.4 累加运算NICE协处理器的设计的更多相关文章

  1. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  2. ruby - 为什么 Object 在 Ruby 中既包含内核又继承它? - 2

    在Ruby(1.8.X)中为什么Object既继承了内核又包含了内核?仅仅继承还不够吗?irb(main):006:0>Object.ancestors=>[Object,Kernel]irb(main):005:0>Object.included_modules=>[Kernel]irb(main):011:0>Object.superclass=>nil请注意,在Ruby1.9中情况类似(但更简洁):irb(main):001:0>Object.ancestors=>[Object,Kernel,BasicObject]irb(main):002:0>Object.included

  3. ruby-on-rails - 带有自定义处理器的 CarrierWave 未注册 - 2

    我正在使用carrierwave上传视频然后有一个名为thumb的版本,带有自定义处理器,可以获取视频并使用streamio-ffmpeg创建屏幕截图。视频和文件都已正确上传,但在调用uploader.url(:thumb)时我得到:ArgumentError:Versionthumbdoesn'texist!VideoUploader.rbrequire'carrierwave/processing/mime_types'require'streamio-ffmpeg'classVideoUploader5)File.renamethumb_path,current_pathendd

  4. ruby - 为什么会存在 Ruby 模块内核? - 2

    在Ruby中的面向对象设计一书中,SandiMetz说模块的主要用途是用它们实现鸭子类型,并将它们包含在每个需要的类中。为什么RubyKernel是包含在Object中的模块?据我所知,它没有在其他任何地方使用。使用模块有什么意义? 最佳答案 理想情况下,Methodsinspirit(适用于任何对象),即使用接收器的方法,应在Object上定义上课,而Procedures(全局提供),即忽略接收者的方法,应该收集在Kernel中模块。Kernel#puts,例如不对其接收者做任何事情;它不调用它的私有(private)方法,它不访

  5. 驱动开发:内核无痕隐藏自身分析 - 2

    在笔者前面有一篇文章《驱动开发:断链隐藏驱动程序自身》通过摘除驱动的链表实现了断链隐藏自身的目的,但此方法恢复时会触发PG会蓝屏,偶然间在网上找到了一个作者介绍的一种方法,觉得有必要详细分析一下他是如何实现的进程隐藏的,总体来说作者的思路是最终寻找到MiProcessLoaderEntry的入口地址,该函数的作用是将驱动信息加入链表和移除链表,运用这个函数即可动态处理驱动的添加和移除问题。MiProcessLoaderEntry(pDriverObject->DriverSection,1)添加MiProcessLoaderEntry(pDriverObject->DriverSection,

  6. ruby - 在 Ruby 中,为什么在注入(inject)/归约方法中将累加器称为 memo? - 2

    出于好奇,为什么在注入(inject)/归约方法中将累加器称为memo?它的命名背后有什么背景/历史吗?它实际上是指“备忘录”还是备忘录代表什么?http://ruby-doc.org/core-2.0/Enumerable.html#method-i-injecthttp://ruby-doc.org/core-2.0/Enumerable.html#method-i-reduce 最佳答案 “memo”表示在内存中,注入(inject)在整个迭代过程中使用来保存中间对象状态,以便在下一次迭代中使用它。

  7. ruby - 为什么我可以使用像 `puts` 这样的内核单例方法? - 2

    在Ruby中,方法puts是Kernel的单例方法模块。通常,当一个模块是included或extend由另一个模块编辑,该模块(但不是它的单例类)被添加到继承树中。这有效地使模块的实例方法可用于模块或其单例类(分别用于include和extend)......但混合模块的单例方法仍然无法访问,因为单例类从未将模块添加到继承树中。那么为什么我可以使用puts(和其他内核单例方法)?Kernel.singleton_methods(false)#=>[:caller_locations,:local_variables,:require,:require_relative,:autolo

  8. ruby - Sidekiq 可以利用多个 CPU 内核吗? - 2

    我是Sidekiq的新手,将它与AmazonEC2实例上的Ruby结合使用,以使用ImageMagick处理图像来完成一些工作。在运行它时,我意识到每个工作人员都在同一个核心上运行。我使用EC2c3.2xlarge机器,它们有8个内核。它显示CPU使用率为15%,但一个内核使用了100%,而其他内核使用了0%。Sidekiq可以为不同的worker使用不同的CPU内核吗?如果可以,这种低效率是由ImageMagic造成的吗?我怎样才能让它使用其他内核? 最佳答案 如果您想使用MRI使用多个内核,则需要启动多个Sidekiq进程;为您

  9. ruby - 为什么某些 Ruby 代码在 2.53GHz 上的运行速度是在 2.2GHz Core 2 Duo 处理器上的两倍? - 2

    (本题试图找出为什么一个程序在不同的处理器上运行会有所不同,所以它与编程的性能方面有关。)以下程序在配备2.2GHzCore2Duo的Macbook上运行需要3.6秒,在配备2.53GHzCore2Duo的MacbookPro上运行需要1.8秒。这是为什么?这有点奇怪……当CPU的时钟速度仅快15%时,为什么要加倍速度?我仔细检查了CPU仪表,以确保2个内核中没有一个处于100%使用率(以便查看CPU是否忙于运行其他东西)。难道是因为一个是MacOSXLeopard,一个是MacOSXSnowLeopard(64位)?两者都运行Ruby1.9.2。pRUBY_VERSIONpRUBY_

  10. 学习 Linux 内核书籍推荐 - 2

    原文链接,欢迎关注:你为什么学习Linux内核?-CodeAllen的回答-知乎https://www.zhihu.com/question/31369673/answer/2894981254主要是工作需要,其实对于我自己的工作来说,在Linux开发的具体业务和算法才是重要的,内核的知识并没有那么重要,对于很多应用开发来说也差不多,最多也是先看看用户态即可。但是出于对技术的追求还是在通过看书和阅读源码学习。书的话主要是看了下边本,其他乱七八糟的还有一些不列举了:深入Linux内核架构这本可能不是那么经典,看这本的原因是网上找到了高清的PDF书籍,于是就画时间看了,结论是非常不错,我很多内核的

随机推荐