免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2318 | 回复: 8
打印 上一主题 下一主题

[内存管理] valotile 与 cache的关系 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-23 20:33 |只看该作者 |倒序浏览
请大家都来讨论下volatile与 cache的关系。

我的理解是:valotile只是告诉编译器不要做优化代码的处理。
如volatile修改的变量,也是cacheable的,那么如下代码:
volatile unsigned char * addp = (volatile unsigned char * )0xc0007000;
int val1,val2;
val1 = *addp;
val2 = *addp;
假设addp所指向的地址是可以cahe的。
那么第一次给val1付值得时候,是从内存去取值。
而第二次就很可能就直接是从cpu的data cache中去取值吧?

不知道我的理解是否对,请大家来讨论下!

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
2 [报告]
发表于 2013-09-23 21:10 |只看该作者
你说的cache的那一段是正确的,但是跟volatile没有关系。volatile只会影响编译器生成的代码,不会影响CPU对内存的cache刷洗

论坛徽章:
0
3 [报告]
发表于 2013-09-23 22:01 来自手机 |只看该作者
我觉得正因为加了volatile,所以编译器应该插入使cache无效的指令,从而导致第二次再去内存中取

论坛徽章:
0
4 [报告]
发表于 2013-09-23 22:07 |只看该作者
volatile纯给编译器看的东西,可以对比下加不加的汇编代码

cache不cache在于你所用的内存页是否带有cache或uncache属性,
普通常用内存一般都是cache的,dma外设用的一般不cache,是因为外设操作的时候会有时序问题,需要刷cache

论坛徽章:
0
5 [报告]
发表于 2013-09-24 08:52 来自手机 |只看该作者
更正下,volatile跟cache没关系,只是防止编译器优化代码,不能保证第二次不去cache中取代码,如果需要保证cache一致性,需要添加另外的指令

论坛徽章:
0
6 [报告]
发表于 2013-09-24 10:24 |只看该作者
我做了如下的试验:
源代码:
#include <stdio.h>

int main()
{
   unsigned int *addp = (unsigned int*)0x80000000;
   int val1,val2;
   val1 = *addp;
   val2 = *addp;
   return val1+val2*2;
}
arm-none-linux-gnueabi-gcc -O2 volatile_test.c -o volatile
arm-none-linux-gnueabi-objdump -D volatile > volatile.dmp
cat volatile.dmp:
000083fc <main>:
    83fc:       e3a03102        mov     r3, #-2147483648        ; 0x80000000
    8400:       e5930000        ldr     r0, [r3]---------------------->去到内存,只取了一次值
    8404:       e0800080        add     r0, r0, r0, lsl #1
    8408:       e12fff1e        bx      lr

将以上源代码添加volatile关键字,修改如下:
#include <stdio.h>

int main()
{
   volatile unsigned int *addp = (volatile unsigned int*)0x80000000;
   int val1,val2;
   val1 = *addp;
   val2 = *addp;
   return val1+val2*2;
}
重复执行以上过程,反汇编,然后cat volatile.dmp:

000083fc <main>:
    83fc:       e3a03102        mov     r3, #-2147483648        ; 0x80000000
    8400:       e5932000        ldr     r2, [r3]------------------------->去到内存取第一次值
    8404:       e5930000        ldr     r0, [r3]------------------------->去到内存取第二次值
    8408:       e0820080        add     r0, r2, r0, lsl #1
    840c:       e12fff1e        bx      lr


注意以上的编译过程,都需要加上优化编译开关:-O2

回复 4# unbutun


   

论坛徽章:
2
酉鸡
日期:2013-09-26 11:11:15摩羯座
日期:2014-01-08 13:45:19
7 [报告]
发表于 2013-09-24 10:34 |只看该作者
回复 1# xiaojsj


    volatile 和cache 没关系
是告诉编译器不要优化的从寄存器取值,每次要从内存取

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
8 [报告]
发表于 2013-09-24 10:57 |只看该作者
volatile和cache没有任何关系

volatile只是告诉gcc,不要优化
比如你连续读取一个地址,gcc可能给你优化为第一次将这个地址的内容读到某个寄存器中,然后后面的读取操作就全部去寄存器中读取了
如果你是读取的设备寄存器来做一个polling,这么优化下来显然逻辑就不对了

cache与否是页表项来控制的,和volatile完全没关系

开关cache只能靠kernel里的代码来做;而volatile是给gcc用的,他不能控制你的cache开关与否

论坛徽章:
0
9 [报告]
发表于 2013-09-26 09:56 |只看该作者
理解,谢谢。回复 8# arm-linux-gcc


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP