免费注册 查看新帖 |

Chinaunix

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

内核同步,优化内存屏障问题。 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2011-10-14 18:46 |只看该作者
回复 31# smalloc


    是啊,这种有可能被优化的问题,最好还是加个保护比较可靠吧。只有等传说中的p姨来证实了{:3_189:}

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
32 [报告]
发表于 2011-10-15 11:09 |只看该作者
回复  eexplorer
cpu有这么智能吗?我绝的不太靠谱,从来没有听说过这样的理论。
ruslin 发表于 2011-10-14 13:10


还真就这么智能,这个是靠谱的。

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
33 [报告]
发表于 2011-10-15 11:26 |只看该作者
回复  ruslin


write a;
barrier();
read b;

我觉得是这样理解(纯属猜测,不对的地方请高手指出 ...
eexplorer 发表于 2011-10-14 11:06



    感觉说的这个场景和中断关系不大。

论坛徽章:
0
34 [报告]
发表于 2011-10-17 11:02 |只看该作者
感觉说的这个场景和中断关系不大。
smalloc 发表于 2011-10-15 11:26


write a;
barrier();
read b;

首先我觉得barrier()应该是针对单cpu的,如果涉及到多cpu的话,就需要使用cpu的memory barrier.

这里加了barrier(),防止了compiler的优化,所以指令是以program order issue给cpu的。但是cpu是有可能乱序执行这两条指令,在大部分情况下是不是先执行read b并不会影响最终的执行结果。但是在某些情况下,假如在write a后发生了中断,并且b的值被修改了,如果read b被先执行了,那么结果就是错的。所以cpu的职能就是在这些情况下,即使乱序执行也要保证read b的结果是正确的

而程序员并不care cpu怎么执行指令,只要最终的结果是正确的,所以他必须确保gcc不要reorder他的指令就行了。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
35 [报告]
发表于 2011-10-17 12:03 |只看该作者
本帖最后由 zylthinking 于 2011-10-17 12:05 编辑
write a;
barrier();
read b;

首先我觉得barrier()应该是针对单cpu的,如果涉及到多cpu的话,就需 ...
eexplorer 发表于 2011-10-17 11:02


有道理
但 “而程序员并不care cpu怎么执行指令,只要最终的结果是正确的,所以他必须确保gcc不要reorder他的指令就行了” 如果离开这个情景推而广之, 似乎值得商榷, 如果那样, 程序员就每必要使用 mb 了, 只要 barrier 足够, 这已经能保证 gcc 不 reorder 他的指令了

论坛徽章:
0
36 [报告]
发表于 2011-10-17 12:33 |只看该作者
回复 36# zylthinking

我是说的在单cpu的前提下。在多cpu下的话,那就要考虑memory barrier了。。。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
37 [报告]
发表于 2011-10-17 22:24 |只看该作者
本帖最后由 chishanmingshen 于 2011-10-17 23:19 编辑

学习了,如果那个靠谱的话.

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
38 [报告]
发表于 2011-10-18 14:16 |只看该作者
本帖最后由 zylthinking 于 2011-10-18 14:47 编辑
还真就这么智能,这个是靠谱的。
塑料袋 发表于 2011-10-15 11:09


在C版看到一帖子, 又发现些不清楚的地方, 关于 volatile 变量。
这个东西应该是内存屏障差不多的东西:

         cpu0                                    cpu1
ptr->buffer = malloc();
wmb();
ptr->enable = true;                       if(ptr->enable){
                                                          // 无rmb()
                                                          memcpy(ptr->buffer, ...);
                                                     }
这个例子, 如果 buffer 属于 volatile 变量, 会不会保证 ptr->buffer 先被 cpu1 感知到; 或者将其隐藏的意思直接表达出来, cpu1 感知 cpu0 所做的改变, 与寄存器值被改变有没有顺序, 可以不可以说寄存器值被改变了, cpu1就一定能感知到吗? 或者进一步, cpu0 发出 invalid request的时机是什么时候???

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
39 [报告]
发表于 2011-10-18 14:36 |只看该作者
本帖最后由 zylthinking 于 2011-10-18 14:44 编辑

我自己推测出一个答案, invalid request 发出时机很可能在内存看到值改变的那一瞬间。 理由是 rmb 的实现基本山都是 invalid cpu1 的 memory cache, 下一次去内存取新值, 那么如果 cpu1 很快去取, 而内存还没有准备好的话, 那就挂了。

但这样推断另一个问题就来了, 首先寄存器到内存的写, 是汇编级别的, 而不是cpu内部实现,
一般写操作, mov memory, register;       register++;       mov register, memory
cpu不可能知道寄存器对应的内存地址, 更不可能跨越程序员肉眼可见的汇编指令直接写到内存;-----有点明白了, 但不清楚对不对, 其实 invalid request 发出时机是执行 mov register, memory 时在 cpu 内部发出的? 或者说的绝对些, 就是写端口完毕后, 发出的???

而如果 invalid request 发出时机是写寄存器, 那么 cpu1 要么无法感知新值; 要么, 在 invalid request中带着新值, 即便带着新值, 一个非常容易出现的情景即可驳斥这种假设, 两个线程对同一个变量自加, 如果 invalid request 带着新值, 则这两个线程就没必要用锁之类的手段保护了

论坛徽章:
0
40 [报告]
发表于 2011-10-18 15:11 |只看该作者
朔料袋兄是在芯片原厂干活的么?对ARM硬件体系理解得非常透彻啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP