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

c 做网站 知乎0元做游戏代理

c 做网站 知乎,0元做游戏代理,中关村在线网站的建设,上海热线新闻网RISC-V IDE MRS2 开发笔记一:volatile关键字的使用 一、volatile是什么 二、GCC 中 volatile 的行为 2.1禁止编译器优化 2.2 不等于内存屏障 2.3 GCC扩展行为 三、什么时候需要 volatile 3.1防止编译器优化掉“有效代码” 3.2 访问硬件寄存器 3.3 中断服务…

RISC-V IDE MRS2 开发笔记一:volatile关键字的使用

一、volatile是什么

二、GCC 中 volatile 的行为
2.1禁止编译器优化
2.2 不等于内存屏障
2.3 GCC扩展行为

三、什么时候需要 volatile
3.1防止编译器优化掉“有效代码”
3.2 访问硬件寄存器
3.3 中断服务程序

四、哪些地方不该用 volatile

一、volatile是什么

在 C 语言中,volatile 是一个类型修饰符,英文的意思是 “易变的”。
它告诉编译器:“这个变量的值随时可能被程序外部因素更改,因此在每次访问时都必须重新从内存中读取。”这意味着编译器不能对使用 volatile 修饰的变量进行编译优化。
在沁恒提供的外设库以及STM32官方库都大量使用了__IO、__O 等,其实本质上都是 volatile:
在这里插入图片描述

二、GCC 中 volatile 的行为
官网描述:
https://gcc.gnu.org/onlinedocs/gccint/Flags.html
https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html

2.1禁止编译器优化

在GCC编译器中,volatile关键字具有优化无关性,其语义行为不受编译优化级别(如-O0、-Os等)的影响。都会在编译阶段禁止一些编译优化,比如,读/写访问的合并、死代码消除、寄存器缓存等。并且在 GCC 的中间表示中,volatile 会被特殊标记,访问 volatile 变量的指令会被标记为 volatile load 或 volatile store,即不可删除、不可合并的访问操作。
GCC 会使用 MEM_VOLATILE_P 标记这些内存访问,告诉中间层和后端:

  • 此内存访问必须按顺序保留
  • 每次访问都必须生成实际的指令

在这里插入图片描述

举个例子:

在这里插入图片描述

在这里插入图片描述

使用 GCC 的 -fdump-rtl-expand 选项可以清晰地看到 volatile 如何影响 RTL 表达式生成。被标记为 volatile 的变量在 RTL 中会显示为 mem/v:SI,其中 /v 表示访问具有 volatile 属性,禁止优化。这与 GCC 对 volatile 的语义一致:始终保持对内存的实际访问,防止编译器优化掉。

2.2 不等于内存屏障

引自官网:https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html
volatile 保证“不会优化掉访问”,但不保证访问顺序,特别是对其他非 volatile 内存的影响顺序。
在这里插入图片描述

不能保证 *ptr = 123; 会在 vobj = 1; 之前执行。因为 *ptr 是普通内存,编译器可以重排这些指令。

在这里插入图片描述

如果需要严格的内存顺序,则必须使用更强的内存屏障(如__asm__ volatile(“” ::: “memory”)) 或使用GCC内置函数(__sync_synchronize())。这样 GCC 会认为 “所有内存都可能被修改”,不会重排 *ptr 和 vobj 的访问顺序。

2.3 GCC扩展行为

还可以配合内联汇编的使用:asm volatile确保汇编指令不被优化删除,即使输出未使用。
在这里插入图片描述

同样可以用 GCC 的 attribute((optimize(“O0”))) 来保护某些函数不被优化。

三、什么时候需要 volatile

3.1防止编译器优化掉“有效代码”

以图二的wait、wait_vol函数为例,其对应的汇编代码如下:
在这里插入图片描述

在 wait 函数中,编译器生成的指令仅在进入函数时读取一次 normal_var 的值(通过 lw 指令加载到 a5 寄存器),然后循环中始终基于该寄存器的值进行判断:如果 normal_var 在循环过程中由外部修改,由于变量未声明为 volatile,编译器假设其值不会被改变,因此不会再次从内存读取。这可能导致程序永远卡在循环中,无法感知变量变化,从而形成死循环。
相比之下,wait_vol 函数中对应的 volatile_var 被声明为 volatile,编译器因此不敢假设其值稳定,每次循环都重新发出 lw 指令,也就是不断从内存读取 volatile_var 的值。这体现了 volatile 的真实作用:强制每次都从内存取值,不允许优化,确保了对变量变化的感知。

3.2 访问硬件寄存器

在嵌入式系统中,经常通过内存映射直接访问硬件寄存器,这些寄存器的值会由外部硬件动态改变,而不是由程序直接控制。如果不加 volatile,编译器可能会出于优化目的缓存寄存器值或省略重复读取,从而导致数据错误。

以MR2创建的CH32V303CBT6模板工程为例,在\CH32V303CBT65\Debug\debug.c文件中,用于printf重定向的_write函数
在这里插入图片描述
在这里插入图片描述

在 _write 中,代码如下所示:
while (*(DEBUG_DATA0_ADDRESS) != 0u) {
// 等待硬件准备好
}
这是一个等待机制,通过while循环持续读取 DEBUG_DATA0_ADDRESS 的值直到硬件写入窗口空闲。如果 DEBUG_DATA0_ADDRESS 未使用 volatile 修饰,编译器可能会将其只读取一次,导致永远无法退出等待循环,进而卡死系统。

3.3 中断服务程序

在嵌入式系统中,中断服务程序与主程序之间共享变量是一种常见的设计模式。为了实现任务的及时响应,某些标志变量或数据缓冲区往往需要在主循环和中断服务程序之间共享。然而,由于中断具有异步性,其对变量的修改可能随时发生,这就要求编译器在访问这类变量时不得进行优化,否则可能导致主程序使用过期的值,从而引发严重逻辑错误。
以沁恒的CH32V307EVT的串口中断为例CH32V307EVT\EVT\EXAM\USART\USART_Interrupt\User\main.c

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

变量 RxCnt1、Rxfinish1 在主程序和 USART2_IRQHandler 中断服务程序中都可能被访问或修改,因此必须用 volatile 修饰,以防止编译器进行缓存优化。如果这些变量未使用 volatile 修饰,主程序可能会将它们的值缓存在寄存器中。
代码如下所示:

while(Rxfinish1 == 0) {
// 等待接收完成
}
如果编译器缓存了 Rxfinish1 的值,那么即使中断函数设置它为 1,主循环仍然会看到旧值(0),从而进入死循环。使用 volatile 后,编译器会强制每次从内存中重新读取变量值,保证获取的是中断修改后的最新状态。

四、哪些地方不该用 volatile

虽然 volatile 是强有力的工具,但滥用也会带来问题:

  • 普通局部变量:局部变量的作用域仅限于函数内部,不会被外部事件(如中断、多线程)修改。使用 volatile 会强制每次访问都从内存读写,禁用寄存器缓存优化,导致性能下降。
  • 多线程同步仅依赖volatile:volatile仅保证可见性(每次访问内存),但不保证原子性或操作顺序。
http://www.dtcms.com/wzjs/528812.html

相关文章:

  • 老男孩设置wordpress数据库静态化优化大师手机版下载安装app
  • 商城网站制作的教程百度热点榜单
  • 重庆网站营销seo推广经验
  • 有做赌博网站的么seo培训公司
  • 上海网站建设的价格网站备案是什么意思
  • 网站建设一条深圳市龙华区
  • 有没有做软件的网站软文网站推广法
  • 网站开发建设挣钱吗宁波seo网络推广定制
  • 如何给网站添加cnzz网络平台
  • 软件推广方案廊坊seo关键词排名
  • 提供做网站班级优化大师app
  • 做外贸推广要做哪些平台合肥seo快排扣费
  • 怎样做一张网站的banner收录查询 站长工具
  • 珠海网站制作渠道关键词竞价排名名词解释
  • wordpress 下一页 模板厦门网站流量优化价格
  • 橙子建站客服电话企业qq官方下载
  • 西宁网站建设开发完整html网页代码案例
  • 网站制作公司有哪些证网站优化排名技巧
  • WordPress数据表性能搜索引擎排名优化方法
  • 做网站自己杭州seo优化公司
  • 一个域名能同时做2个网站吗现在最火的推广平台有哪些
  • 手机网站是怎么做的山东企业网站建设
  • 企网官方网站百度app交易平台
  • 网站建设通网站域名注册查询
  • 上海高端网站公司怎么把产品放到网上销售
  • 做自媒体挣钱的网站有哪些百度电视剧风云榜
  • 17网站一起做网店普石家庄网站建设
  • 网站做seo安全吗湖南seo网站开发
  • 呼伦贝尔市住房和城乡建设委网站百度seo系统
  • 大连 响应式网站seo公司是什么