0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RISC-V中一个优化导致的问题案例

嵌入式USB开发 来源:嵌入式USB开发 作者:嵌入式USB开发 2023-06-08 10:02 次阅读

本文转自公众号,欢迎关注

优化导致的问题案例 (qq.com)

  • 一.过程
  • 二.思考

一.过程

关键代码如下

通过串口驱动接口,注册串口接收回调函数,uart_rx_callback

该回调函数中如果收到串口数据,长度非0,则更新全局变量uart_rx_len

主循环中再检查全局变量uart_rx_len,如果大于0说明收到了串口数据,将收到的数据再发送出去,实现简单的串口回环测试。

static int uart_rx_len = 0;
void uart_rx_callback(const void *buffer, uint32_t length)
{
    if(length >0)
    {
        uart_rx_len = length;
    }
}
int main(void)
{
    ......
    debug_uart_init(IOT_UART_PORT_1);
    uint8_t buffer[64];
    iot_uart_register_rx_callback(IOT_UART_PORT_1,buffer,sizeof(buffer),uart_rx_callback);
    while(1)
    {
        if(uart_rx_len > 0)
        {
            iot_uart_write_buffer(IOT_UART_PORT_1,buffer,uart_rx_len);
            uart_rx_len=0;
        }
    }
}

现象是并没有实现上述回环测试的功能。

于是进行调试,先确认是否进入了接收处理,

b uart_rx_callback

发现可以进入该回调函数,说明收到了数据。

step单步运行到执行完uart_rx_len = length;,再查看该变量的值

(gdb) p uart_rx_len
$2 = 1

也确实收到了一个字节。

然后继续往下看,看如下条件是否进入

if(uart_rx_len  > 0)
        {
            iot_uart_write_buffer(IOT_UART_PORT_1,buffer,uart_rx_len);
            uart_rx_len=0;
        }

b main.c:146iot_uart_write_buffer(IOT_UART_PORT_1,buffer,uart_rx_len所在行146行,打断点。

发现进不了该断点。

这里就比较奇怪了,前面uart_rx_len确实是1,了但是这里条件却进不去,其他地方也没有写uart_rx_len的地方。

那么只有继续看该处代码对应的汇编代码

先在uart_rx_callback前打断点,串口接收一个字节触发该回调执行。再在 if(uart_rx_len > 0)所在的行144行前打断点,b main.c:144c运行到该处。

此时看到uart_ex_len的值是1正确的。

(gdb) p uart_rx_len
$2 = 1

layout split打开汇编和C对照窗口。

查看变量uart_rx_len的地址,为0x20300c8

(gdb) p &uart_rx_len
$4 = (int *) 0x20300c8 < uart_rx_len >
(gdb) info reg s1
s1             0x2030000        33751040

S1寄存器的值设置为0x2030000, lui s1,0x2030 lui的u表示up(高20位),加载0x2030到S1的高20位。

lw a2,200(S1)即将S1对应的地址偏移200(0xC8)地址处的值加载到a2寄存器。

正好是获取0x2030C8(uart_rx_len)的值到A2,

然后再执行

blez a2,0x20001ba进行判断uart_rx_len和0的值比较,判断是否往下执行还是在此死循环。

图片

初看没问题,一细看就有端倪了。

假设一开始uart_rx_len=0,

那么后面始终执行的是一条语句,blez a2,0x20001ba,a2寄存器的值不再更新了,这就有问题了,内存中0x2030C8(uart_rx_len)的值变了,但是寄存器a2的值不再变化。

这就是编译器自作主张优化,生成的代码没有继续去从内存0x2030C8(uart_rx_len)处更新值到a2寄存器了。理论上是需要再次执行上述lw a2,200(S1)指令的。这就编译器优化导致的问题。

我们修改

static int uart_rx_len = 0;

改为

`static volatile int uart_rx_len = 0;``

再来看汇编代码。

可以看到如果a5小于0,会跳转到addi s1,s2,200处执行再继续lw a5,0(S1)处加载uart_rx_len的值到a5,会不断从内存处更新值到寄存器。

图片

这就是volatile的作用,加了volatile后编译器始终,会从内存中更新值到寄存器,而不会自作主张使用寄存器中缓存的值。

默认SCons/riscv_tools.py中是Os优化,

CCFLAGS = common_flags + [
        "-Os",
    ]

不加volatile且优化改为

-O3,-O2,-O1,-O0分别看一下。

可以看到-O1优化编译就进行了优化,后面-O2,-O3就不用看了。

-O0

图片

-O1

图片

二.思考

这里函数uart_rx_callback写了变量uart_rx_len

void uart_rx_callback(const void *buffer, uint32_t length)
{
    if(length >0)
    {
        uart_rx_len = length;
    }
}

且uart_rx_callback函数也作为回调函数使用了,理论上编译器应该指导uart_rx_len会被改写,不应该作此优化。

手动调用以下uart_rx_callback

uart_rx_callback(0, 0);
    debug_uart_init(IOT_UART_PORT_1);

还是一样的优化了

图片

看来编译器还是聪明过头了。

这里主要是

while(1)后面第一条语句就是判断uart_rx_len,如果之前还有其他语句,则编译器可能不会优化了。

while(1)

    {

        if(uart_rx_len > 0)

        {

            iot_uart_write_buffer(IOT_UART_PORT_1,buffer,uart_rx_len);

            uart_rx_len=0;

        }

    }

图片

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5082

    文章

    19108

    浏览量

    304836
  • 串口
    +关注

    关注

    14

    文章

    1551

    浏览量

    76433
  • 优化
    +关注

    关注

    0

    文章

    220

    浏览量

    23890
  • 函数
    +关注

    关注

    3

    文章

    4327

    浏览量

    62574
  • RISC-V
    +关注

    关注

    45

    文章

    2271

    浏览量

    46131
收藏 人收藏

    评论

    相关推荐

    rIsc-v的缺的是什么?

    态系统还不够丰富。这可能导致软件和工具的可用性受限,特别是在些特定的应用领域或开发环境中。开发者可能需要投入更多的时间和精力来寻找或开发适合RISC-V架构的软件和工具链。 碎片化风险:由于
    发表于 07-29 17:18

    risc-v的发展历史

    RISC-V的发展历史可以追溯到2006年左右,当时David Patterson和其他研究者开始探索创建开放和可扩展的指令集架构(ISA)。以下是RISC-V发展的主要里程碑:
    发表于 07-29 17:20

    关于RISC-V学习路线图推荐

    号的RISC-V学习路线图可以帮助学习者系统地掌握RISC-V架构的相关知识。比如以下是
    发表于 11-30 15:21

    为什么选择RISC-V

    。例如,如果工程师在FPGA中实现软RISC-V内核,则通常可以使用RTL源代码。由于RISC-V免版税,这为将基于RISC-V的设计从FPGA移植到ASIC或另一个FPGA带来了极大
    发表于 07-27 17:38

    如何设计好的RISC-V

    文章目录写在前面什么是RISC-VRISC-V诞生的背景ISA霸权摩尔定律的穷途末路穷困潦倒的学者不断增长的指令数量RISC-V架构设计思想如何设计好的ISARISC-
    发表于 07-26 06:42

    RISC-V MCU开发相关资料分享

    开发工作中。 工欲善其事必先利其器,要想实现基于RISC-V MCU的项目开发,与之配套的集成开发环境必不可少。目前市场上可供选择的RISC-V MCU开发工具已初具规模,由MounRiver团队打造的MounRiver® Studio(MRS)便是其
    发表于 11-10 07:50

    优化的关键,RISC-V中的性能监控

    RISC-V在云端、数据中心、汽车与网络技术中的频繁创新和亮相,已经让这成长中的ISA只脚迈入了高性能计算场景。然而缺少强大的性能监测工具让RISC-V的应用
    发表于 12-27 08:00

    risc-v峰会亮点 RT-Thread对RISC-V的支持

    在第RISC-V中国峰会上看点很多,我们来看看risc-v峰会其中一非常重要的亮点 ;RT-Thread对
    发表于 06-23 11:29 7848次阅读
    <b class='flag-5'>risc-v</b>峰会亮点 RT-Thread对<b class='flag-5'>RISC-V</b>的支持

    risc-v中国峰会直播:如何优化RISC-V指令集架构的代码密度?

    届中国峰会在上海举办,以下是小编整理的部分risc-v峰会的内容。主要介绍了影响代码密度的因素以及如何优化RISC-V指令集架构的代码密度?感兴趣的小伙伴可以详细了解
    的头像 发表于 06-23 12:12 3114次阅读
    <b class='flag-5'>risc-v</b>中国峰会直播:如何<b class='flag-5'>优化</b><b class='flag-5'>RISC-V</b>指令集架构的代码密度?

    RISC-V峰会看点 RISC-V如何进入服务器、高性能市场

    在第RISC-V中国峰会上看点很多,我们来看看risc-v峰会其中一非常重要的亮点 ;RISC-V
    发表于 06-23 14:14 8455次阅读
    <b class='flag-5'>RISC-V</b>峰会看点 <b class='flag-5'>RISC-V</b>如何进入服务器、高性能市场

    RISC-V中国峰会看点 risc-v开发要怎么优化risc-v指令集架构代码密度

    在第RISC-V中国峰会上看点很多,RISC-V是开源的,那么代码密度要怎么控制,会不会因为开源而导致代码密度特别大? 我们起来看看
    发表于 06-23 18:22 9675次阅读
    第<b class='flag-5'>一</b>届<b class='flag-5'>RISC-V</b>中国峰会看点 <b class='flag-5'>risc-v</b>开发要怎么<b class='flag-5'>优化</b><b class='flag-5'>risc-v</b>指令集架构代码密度

    RISC-V,真的要上天了!

    X280,是多核、多集群能力的 RISC-V处理器,提供了对RISC-V矢量扩展标准和SiFive智能扩展的全面支持,并针对边缘的AI/ML计算进行了
    的头像 发表于 09-09 09:59 800次阅读

    RISC-VRISC-V AI的未来(特邀讲座)

    主题演讲:RISC-VRISC-V AI的未来(特邀讲座)ppt分享
    发表于 07-14 17:15 16次下载

    RISC-V生态强劲 RISC-V International会员超4000 超75技术工作组

    的 4,000 多名成员,拥有超过 75 技术工作组,推动 RISC-V 标准、软件、工具等方面的进展。仅今年年,RISC-V 就批准了 12 项规范,还有更多规范即将批准。此外,
    的头像 发表于 11-09 15:17 762次阅读

    RISC-V为何如此重要?

    本文由半导体产业纵横(ID:ICVIEWS)编译自xda-developersRISC-V正在缓慢而悄然地改变CPU市场。RISC-V在过去几年中一直是行业流行语,它正在慢慢改变半导体市场。但是
    的头像 发表于 04-29 08:28 381次阅读
    <b class='flag-5'>RISC-V</b>为何如此重要?