免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 南海一钓叟
打印 上一主题 下一主题

那为大侠给俺讲讲cache和volatie变量的关系 [复制链接]

论坛徽章:
0
81 [报告]
发表于 2008-03-20 22:15 |只看该作者
原帖由 cunettenuc 于 2008-3-20 20:05 发表



我有一个问题想请教, 就是在多线程中, 有一个全局变量没有用volatile去修饰, 而我只是用锁去进行互斥地访问.
那么假如我线程1在执行时将这个变量放到了cache中, 有没有这种可能: 也就是在放弃锁的时候这 ...

前面已经说了,如果读的线程和写的线程在一个CPU,那么它直接从cache里读到这个变量的值。
如果读的线程在另一个CPU,那么硬件保证了cache的一致性,见前面的帖子。
两种情况都保证读到的值是最新的

论坛徽章:
0
82 [报告]
发表于 2008-04-03 09:43 |只看该作者
我是服了
cu上就是高手如林

论坛徽章:
0
83 [报告]
发表于 2011-03-18 14:28 |只看该作者
mark一记

论坛徽章:
0
84 [报告]
发表于 2011-03-18 15:49 |只看该作者
mark

对C编译器来说,应该是只有内存和寄存器的概念,不知道有cache.cache和内存的同步是由硬件保证的应该

论坛徽章:
0
85 [报告]
发表于 2011-03-20 02:10 |只看该作者
写一段代码来试验下:
volatile.c

  1. #include <stdio.h>


  2. int volatile mytest = 1;
  3. int main ()
  4. {
  5.         mytest= 3;
  6.         mytest = 4;
  7.         printf("mytest = %d\n", mytest);
  8.         return 0;
  9. }
复制代码
non_volatile.c

  1. #include <stdio.h>


  2. int mytest = 1;
  3. int main ()
  4. {
  5.         mytest= 3;
  6.         mytest = 4;
  7.         printf("mytest = %d\n", mytest);
  8.         return 0;
  9. }
复制代码
编译:
gcc -O2 -o volatile volatile.c
objdump -D volatile > volatile_dump

gcc -O2 -o non_volatile non_volatile.c
objdump -D non_volatile > nonvolatile_dump


objdump之:
volatile_dump

  1. 08048328 <main>:
  2. 8048328:       55                      push   %ebp
  3. 8048329:       89 e5                   mov    %esp,%ebp
  4. 804832b:       83 ec 08                sub    $0x8,%esp
  5. 804832e:       83 e4 f0                and    $0xfffffff0,%esp
  6. 8048331:       c7 05 28 94 04 08 03    movl   $0x3,0x8049428
  7. 8048338:       00 00 00
  8. 804833b:       c7 05 28 94 04 08 04    movl   $0x4,0x8049428
  9. 8048342:       00 00 00
  10. 8048345:       83 ec 08                sub    $0x8,%esp
  11. 8048348:       a1 28 94 04 08          mov    0x8049428,%eax
  12. 804834d:       50                      push   %eax
  13. 804834e:       68 08 84 04 08          push   $0x8048408
  14. 8048353:       e8 10 ff ff ff          call   8048268 <_init+0x38>
  15. 8048358:       31 c0                   xor    %eax,%eax
  16. 804835a:       c9                      leave
  17. 804835b:       c3                      ret
复制代码
non_volatile_dump

  1. 08048328 <main>:
  2. 8048328:       55                      push   %ebp
  3. 8048329:       89 e5                   mov    %esp,%ebp
  4. 804832b:       83 ec 08                sub    $0x8,%esp
  5. 804832e:       83 e4 f0                and    $0xfffffff0,%esp
  6. 8048331:       83 ec 08                sub    $0x8,%esp
  7. 8048334:       6a 04                   push   $0x4
  8. 8048336:       68 fc 83 04 08          push   $0x80483fc
  9. 804833b:       c7 05 1c 94 04 08 04    movl   $0x4,0x804941c
  10. 8048342:       00 00 00
  11. 8048345:       e8 1e ff ff ff          call   8048268 <_init+0x38>
  12. 804834a:       31 c0                   xor    %eax,%eax
  13. 804834c:       c9                      leave
  14. 804834d:       c3                      ret
  15. 804834e:       90                      nop
  16. 804834f:       90                      nop
复制代码
很明显,volatile.c里的两次变量赋值未被优化掉,non_volatile.c里的两次变量赋值被优化成一次。
所以volatile关键字是起到了对编译器指示的作用,指示编译器不要对volatile的变量做优化。

论坛徽章:
0
86 [报告]
发表于 2011-03-24 01:42 |只看该作者
  1. volatile int i;
  2.    int j;
  3. void main (void)
  4. {
  5.   i = 1;  //1  不被优化 i=1
  6.   i = 2;  //2  不被优化 i=2
  7.   i = 3;  //3  不被优化 i=3
  8.   
  9.    j = 1;  //4  被优化
  10.    j = 2;  //5  被优化
  11.    j = 3;  //6  j = 3
  12. }
复制代码
  1.   i = 1;  //1  不被优化 i=1
  2. 0041138E  mov         dword ptr [i (417164h)],1
  3.   i = 2;  //2  不被优化 i=2
  4. 00411398  mov         dword ptr [i (417164h)],2
  5.   i = 3;  //3  不被优化 i=3
  6. 004113A2  mov         dword ptr [i (417164h)],3
  7.   
  8.    j = 1;  //4  被优化
  9. 004113AC  mov         dword ptr [j (417160h)],1
  10.    j = 2;  //5  被优化
  11. 004113B6  mov         dword ptr [j (417160h)],2
  12.    j = 3;  //6  j = 3
  13. 004113C0  mov         dword ptr [j (417160h)],3
复制代码
请问为什么我的编译器没有把不带volatile的变量优化掉呢?

论坛徽章:
0
87 [报告]
发表于 2011-03-24 01:43 |只看该作者
我在VS2005中编译的,然后看的反汇编。

论坛徽章:
0
88 [报告]
发表于 2011-03-29 18:23 |只看该作者
volatile只是在编译过程中保证不被优化掉,而是否经过cache是由MMU控制的,两者之间没关系……

论坛徽章:
0
89 [报告]
发表于 2011-03-29 20:48 |只看该作者
强贴留名。。。

论坛徽章:
0
90 [报告]
发表于 2011-04-05 22:44 |只看该作者
mark一下,有时间再看。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP