当前位置: 首页 > wzjs >正文

公司让我做网站负责人上海有名网站建站开发公司

公司让我做网站负责人,上海有名网站建站开发公司,wordpress如何添加栏目,wordpress博客添加ico图标文章目录 memcpy RISC-V 汇编代码分析:内存复制函数1. 初始检查和参数设置2. 64字节块复制(优化路径)64字节复制循环体 3. 8字节块复制8字节复制循环体 4. 单字节复制(剩余部分)5. 函数返回关键优化点结论 问题现象&am…

文章目录

    • memcpy
  • RISC-V 汇编代码分析:内存复制函数
    • 1. 初始检查和参数设置
    • 2. 64字节块复制(优化路径)
      • 64字节复制循环体
    • 3. 8字节块复制
      • 8字节复制循环体
    • 4. 单字节复制(剩余部分)
    • 5. 函数返回
    • 关键优化点
    • 结论

问题现象:在VDK软件中,SDMA接受从SCP/AP侧发来的命令帧后自动解析命令帧,然后执行相应操作,但是在使用SCP 给 SDMA发送命令帧时,发现SDMA的回调调用了多次,因此查看反汇编出来的代码,是否给SDMA的interface发送了多次的transaction,造成了回调调用多次。
猜测:memcpy时,是多次transaction
SCP测试代码如下:

SDMA_BRUST_HEAD sdma_frame_;
uintptr_t addr_sdma_ = (0x11002000);
memcpy(addr_sdma_, &sdma_frame_, sizeof(SDMA_BRUST_HEAD));

需要调试的sdma代码如下

/* 1 */
lui a5, 0xe0           # 将 0xe0 << 12 = 0xe0000 加载到 a5 高20位
c.addi a5, 20          # a5 = 0xe0000 + 20 = 0xe0014
c.sd a5, 32(sp)        # 将 a5 的值存储到 [sp+32] 的内存位置
c.ld a5, 32(sp)        # 从 [sp+32] 重新加载到 a5 (看起来冗余)
c.ld a5, 32(sp)        # 再次加载 (可能是编译器生成的冗余指令)
sw zero, 0(a5)         # 将 0 写入 [a5+0] 的内存位置
/* 2 */
lui a5, 0x11002        # 加载 0x11002000 到 a5
c.sd a5, 24(sp)        # 存储目标地址到 [sp+24]
c.mv a5, sp            # a5 = sp (栈指针)
c.li a2, 1             # a2 = 1 (复制长度=1字节)
c.mv a1, a5            # a1 = sp (源地址)
c.ldsp a0, 24(sp)      # a0 = [sp+24] = 0x11002000 (目标地址)
jal ra, 0xe000000000fd <memcpy> # 调用 memcpy
  1. 地址加载与存储(这段代码将0xe0014地址处的内存清零)
  2. 准备memcpy参数(准备参数并调用memcpy,将栈上1字节数据复制到0x11002000地址)

最关键的部分来了

memcpy

c63d      c.beqz  a2,0xe00001046 
82aa     c.mv t0, a0
83b2     c.mv t2, a2
fc03f31     andi t1, t2, -64
9316     c.add t1, t0
0255863     bge a0, t1, 0xe000f4c
6190     c.ld a2, 0(a1)
6594     c.ld a3, 8(a1)
6998     c.ld a4, 16(a1)
6d9c     c.ld a5, 24(a1)
e110     c.sd a2, 0(a0)
e514     c.sd a3, 8(a0)
e918     c.sd a4, 16(a0)
ed1c     c.sd a5, 24(a0)
7190     c.ld a2, 32(a1)
7594     c.ld a3,40(a1)
7998     c.ld a4,48(a1)
7d9c     c.ld  a5,56(a1)
f110     c.sd a2, 32(a0)
f514     c.sd a3, 40(a0)
f918     c.sd a4, 48(a0)
fd1c     c.sd a5, 56(a0)
04058593     addi a1, a1, 64
04050513     andi a0, a0, 64fc654ce3      blt a0, t1,0xe000000fe8 <memcpy+0x10>
ff83f313      andi t1, t2, -8
0053033     addi a0, t1, t0
0655863      bge a0, t1,0xe00000102c <_loader_start+0x2c>
6190       c.ld a2, 0(a1)
0521       c.addi a1, 8
e110       c.sd a2, 0(a0)0521       c.addi a0, 8
fe654ce3      blt a0, t1,0xe000001020 <_loader_start+0x20>
00728333     add t1, t0, t2
00655a63       bge a0, t1,0xe000001044 <_loader_start+0x44>
005c603      lbu a2, 0(a1)
0585       c.addi a1, 1
00c50023      sb a2, 0(a0)
0505       c.addi a0, 1
fe654ae3      blt a0, t1,0xe000001034 <__loader_start+0x34>
8516       c.mv a0, t0
8082       c.jr ra

RISC-V 汇编代码分析:内存复制函数

这段代码实现了一个优化的内存复制函数(memcpy),我将其分为几个关键部分进行分析:

1. 初始检查和参数设置

c63d      c.beqz  a2,0xe00001046    # 如果复制长度(a2)为0,直接跳转到结束
82aa     c.mv t0, a0               # 保存原始目标地址到t0
83b2     c.mv t2, a2               # 保存原始长度到t2

2. 64字节块复制(优化路径)

fc03f31     andi t1, t2, -64       # 计算64字节对齐的长度
9316     c.add t1, t0              # t1 = 目标地址 + 对齐长度
0255863     bge a0, t1, 0xe000f4c  # 如果不需要64字节复制,跳转到小数据复制

64字节复制循环体

6190     c.ld a2, 0(a1)           # 从源地址加载8字节
6594     c.ld a3, 8(a1)           # 加载+8字节
6998     c.ld a4, 16(a1)          # 加载+16字节
6d9c     c.ld a5, 24(a1)          # 加载+24字节
e110     c.sd a2, 0(a0)           # 存储到目标地址
e514     c.sd a3, 8(a0)           # 存储+8字节
e918     c.sd a4, 16(a0)          # 存储+16字节
ed1c     c.sd a5, 24(a0)          # 存储+24字节
7190     c.ld a2, 32(a1)          # 加载+32字节
7594     c.ld a3,40(a1)           # 加载+40字节
7998     c.ld a4,48(a1)           # 加载+48字节
7d9c     c.ld a5,56(a1)           # 加载+56字节
f110     c.sd a2, 32(a0)          # 存储+32字节
f514     c.sd a3, 40(a0)          # 存储+40字节
f918     c.sd a4, 48(a0)          # 存储+48字节
fd1c     c.sd a5, 56(a0)          # 存储+56字节
04058593     addi a1, a1, 64      # 源地址+64
04050513     addi a0, a0, 64      # 目标地址+64
fc654ce3      blt a0, t1,0xe000000fe8 # 循环直到完成所有64字节块

3. 8字节块复制

ff83f313      andi t1, t2, -8     # 计算8字节对齐的长度
0053033       add t1, t0, t1      # t1 = 目标地址 + 对齐长度
0655863      bge a0, t1,0xe00000102c # 如果不需要8字节复制,跳转到单字节复制

8字节复制循环体

6190       c.ld a2, 0(a1)         # 加载8字节
0521       c.addi a1, 8           # 源地址+8
e110       c.sd a2, 0(a0)         # 存储8字节
0521       c.addi a0, 8           # 目标地址+8
fe654ce3      blt a0, t1,0xe000001020 # 循环直到完成所有8字节块

4. 单字节复制(剩余部分)

00728333     add t1, t0, t2       # t1 = 原始目标地址 + 原始长度
00655a63       bge a0, t1,0xe000001044 # 检查是否已完成
005c603      lbu a2, 0(a1)        # 加载1字节
0585       c.addi a1, 1           # 源地址+1
00c50023      sb a2, 0(a0)        # 存储1字节
0505       c.addi a0, 1           # 目标地址+1
fe654ae3      blt a0, t1,0xe000001034 # 循环直到完成所有单字节

5. 函数返回

8516       c.mv a0, t0            # 返回原始目标地址
8082       c.jr ra                # 返回调用者

关键优化点

  1. 分层复制策略:先尝试64字节块复制,然后是8字节块,最后是单字节
  2. 寄存器重用:使用a2-a5作为临时寄存器加载/存储数据
  3. 循环展开:64字节复制部分完全展开,避免循环开销
  4. 压缩指令:大量使用c.xxx压缩指令减少代码大小

这个实现是典型的memcpy优化,优先处理大块对齐数据以获得最佳性能,然后处理剩余的小数据。

结论

答案已经很明显了,结果就是因为memcpy会分层复制,导致了给interface 传不定次的 transaction, 解决方案也很简单,根据帧格式,去解析指令,每次来的transaction,提取其中的数据,将其push_back 到 vector中,每当收集到tail帧,就解析整个帧,执行相应逻辑后,clear整个vector,问题完美解决,最后贴一下解决的代码

void SysDMA::handle_sdma_disp_cmd_if_protocol_engine_b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& time) {// FLYME: Default implementation. Implement this.for (int i = 0; i < trans.get_data_length(); ++i) {dispatch_frame._push_back(*(trans.get_data_ptr() + i));}for (int i = 0; i < dispatch_frame_size(); ++i) {if (i % 16 == 0 && dispatch_frame_size() % 16 == 0) {uint8_t temp = dispatch_frame[i] & 2;if (temp) {HandleTransactionData(dispatch_frame_data());dispatch_frame.clear();}}trans.set_response_status(tlm::TLM_OK_RESPONSE);}
}

代码分析:

  1. 这是一个SystemC TLM模型的DMA处理函数
  2. 首先将传输数据(trans)逐个字节推入dispatch_frame缓冲区
  3. 然后检查dispatch_frame中的数据,每16字节检查一次特定标志位(第2位)
  4. 如果标志位被设置,则调用HandleTransactionData处理数据并清空缓冲区
  5. 最后设置传输响应状态为OK
http://www.dtcms.com/wzjs/510353.html

相关文章:

  • 怎么做网站赚钱怎样去推广自己的网店
  • 个人网站做影视成都官网seo厂家
  • 上高县城乡规划建设局网站小说风云榜
  • 做网站如何计算工资爱站网官网关键词
  • 北京企业网站建设公司百度收录网站多久
  • dw做不了动态网站asp赣州seo唐三
  • 设计实例网站企业培训课程设置
  • 外贸推广软件seo系统推广
  • 宁波专业做网站公司小红书关键词排名优化
  • 国内网站开发的主流技术抖音代运营公司
  • 猪八戒网站做私活赚钱吗武汉seo搜索引擎
  • 客户网站建设问题seo网络推广是干嘛的
  • 苏州吴江区建设局网站抓关键词的方法10条
  • 网站策划书结尾专业做网站建设的公司
  • 湛江做网站服务热线太原seo管理
  • 做网站运营有前途热搜榜百度
  • 网站建设思企互联媒体:多地新增感染趋势回落
  • boostrop怎么做网站今日军事新闻头条新闻
  • 好网站建设公司开发方案品牌广告视频
  • 淮北哪里做网站sem竞价外包公司
  • 网站开发实训新的体会湖南省人民政府官网
  • 网站开发与解决技巧东莞产品网络推广
  • iis搭建多个网站深圳做网站seo
  • 杭州网站建设培训太原关键词排名优化
  • 古风自己做头像的网站免费seo技术教程
  • 做韦恩图的网站网站seo提升
  • 周口网站建设360站长工具seo
  • 想自己做淘宝有什么网站吗百度推广账号怎么注册
  • 成都装修公司推荐网站seo推广员招聘
  • 临汾做网站的公司可以营销的十大产品