免费注册 查看新帖 |

Chinaunix

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

C语言标准有没有规定前一个语句必须在后一个语句之前完成? [复制链接]

论坛徽章:
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
51 [报告]
发表于 2011-10-18 16:22 |只看该作者
你说的情况真的可能发生?
页也是有粒度与边界的,cache也是有关联性(associativity)的。
映射关系不是任意的、极度灵活的(不知道该怎么描述)。
lz以及zylthinking并没有指出两成员间的地址差,但也不会特别大吧?OwnWaterloo 发表于 2011-10-18 16:11


我是学计算机的,而你不是,所以这一切都完全有可能发生。

而且和cache的associativity没有关系。 硬说和cache有关系的话,就是VIVT的cache则根本不需要经过TLB转换这一步。

论坛徽章:
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
52 [报告]
发表于 2011-10-18 16:24 |只看该作者
本帖最后由 zylthinking 于 2011-10-18 16:49 编辑
  

为本地CPU访问某地址时,是在同时查找load store queue和cache。  各读写永远顺序的进入load store queue,乱序的从load store queue出来并进入cache。
塑料袋 发表于 2011-10-18 16:16

各读写永远顺序的进入load store queue,乱序的从load store queue出来并进入cache。
我感觉似乎明白在说什么, 但还是没明白整体在说什么;

具体到这个问题, ptr->buf = xxx; ptr->enable = true; 之间到底会不会发生乱序呢?
具体而言; 就是如果发生乱序, 而 ptr->enable 确实和 buf 物理地址相同的话, 会发生什么动作呢?

是不是执行 ptr->buf赋值时, 发现了问题, 回滚 ptr->enable; 然后等 buf 赋值执行完毕, 再次执行 enable 赋值; 还是直接忽视 buf = xxx 这个语句?
无论哪种, 都感觉有问题, 因为 enable 的结果很可能已经写到了cpu 外, 从而被寄存器等感知---只要不是顺序写保证的CPU, 就有这个可能, 那么, 即便它回滚, 也有一个窗口期

另外, 这里潜在的关联导致的结果就是不能乱序吗, 我还是没明白本地CPU看到的永远是循序读写和这个有什么联系; 我觉得在一定程度上是理解 “本地CPU看到的永远是循序读写” 的意思的;

论坛徽章:
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
53 [报告]
发表于 2011-10-18 16:26 |只看该作者
zylthinking,是否可以这样理解?

volatile保证生成的二进制代码里的顺序性。
但即使二进制代码里有顺序 ...
AD8018 发表于 2011-10-18 16:11


似乎是这样, 但那个volatile的顺序保证那句话, 我还晕着呢, 不知道保证的是volatile变量之间的顺序, 还是 volatile 变量和普通变量的顺序

论坛徽章:
0
54 [报告]
发表于 2011-10-18 16:26 |只看该作者
回复 44# 狗蛋


    另外,类似本帖讨论的问题,实践上是不会遇到或者说不应该遇到的。


因为,原则上说,连“为int赋值”这个操作,都不保证是原子的。

也就是说,如果你在A线程设置int flag为0xffff,切换到B线程的时候,不保证不会遇到“flag被设置了一半”这种诡异状态。


连一个flag本身都无法保证,何况是两个flag之间的修改次序?


唯一可“保证你的程序正确”的,就是锁/临界区/旗标之类“正规”机制——读一个东西,加锁;写一个东西,加锁;如果一组变量的状态是相关的,那么把它们整体当成一个资源,加锁保证它们整体状态的原子性。

所以,玩多线程,最好不要随意尝试“优化”,除非你知道自己在做什么。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
55 [报告]
发表于 2011-10-18 16:27 |只看该作者
回复 50# 塑料袋

也就是说CPUA自己无论它对外部怎么样store / load,它自己本身是不会感觉到的,始终认为自己是顺序的在store / load。

这个只是站在CPUA的视角上,是在顺序的store / load,但是对外部而言,比如外设的视角上:有可能先发送过来的是数据,后面才发送过来地址吧?

如果只在CPUA的视角上,程序顺序执行没有问题,那么就只是需要barrier();如果需要在外部的视角上,也要求程序顺序执行,才需要内存屏障?

论坛徽章:
0
56 [报告]
发表于 2011-10-18 16:42 |只看该作者
似乎是这样, 但那个volatile的顺序保证那句话, 我还晕着呢, 不知道保证的是volatile变量之间的顺序, ...
zylthinking 发表于 2011-10-18 16:26



   可能不完全是volatile, msdn中提到全局和静态变量:
when optimizing, the compiler must maintain ordering among references to volatile objects as well as references to other global objects. In particular,

A write to a volatile object (volatile write) has Release semantics; a reference to a global or static object that occurs before a write to a volatile object in the instruction sequence will occur before that volatile write in the compiled binary.

A read of a volatile object (volatile read) has Acquire semantics; a reference to a global or static object that occurs after a read of volatile memory in the instruction sequence will occur after that volatile read in the compiled binary.

This allows volatile objects to be used for memory locks and releases in multithreaded applications.

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
57 [报告]
发表于 2011-10-18 16:42 |只看该作者
本帖最后由 OwnWaterloo 于 2011-10-18 16:43 编辑
我是学计算机的,而你不是,所以这一切都完全有可能发生。
塑料袋 发表于 2011-10-18 16:22


你猜对了,我确实不是。但我不认为这点可以作为后半句的论据。


本楼讨论的是"两语句的顺序是否有保证"。 或者说白一点:这里是否需要加屏障?
找出个别的机器,说两语句有关联、有顺序、不用加,也有用处,但不如上面大。


代码演化的流程是这样:
ptr->buffer = malloc(...);
barrier();
ptr->enable = 1;

当效率不足,且某个特定机器这两句当真有关联,且编译器提供的barrier没有优化为空,才会将代码演化为这样:
ptr->buffer = malloc(...);
#if ...
barrier();
#endif
ptr->enable = 1;

而且很有可能没有这样演化的机会。


我是学工程的。但我不知道上面的做法是否普遍,正确。反正我就会这么干。


另外,我质疑的其实是这句话:
>> 因为这两句话完全有可能在对同一个地址进行写操作。谁也不知道在经过TLB转换地址后,ptr->buf和ptr->enable这两个虚拟地址,是不是转换成了同一个物理地址。
你能给出任一一种满足
struct {
      // 这里随便你写
      int* buffer;
      // 这里也随便你写
      int enable;
      // 这里依然随便你写
} *ptr;
但在一个进程执行过程当中,ptr->buffer与ptr->enable转换成了同一物理地址的情况吗?

论坛徽章:
0
58 [报告]
发表于 2011-10-18 16:52 |只看该作者
Mark

论坛徽章:
0
59 [报告]
发表于 2011-10-18 16:52 |只看该作者
倒,终于看明白了,可分解为三个话题,应该有比较确定的答案。

1. C语言能否保证生成二进制代码中的指令顺序。
   如果可以,用什么办法保证?

2. 对于用户态程序的二进制代码(含多线程),
   能否保证本CPU的二进制代码的执行顺序?
   能否保证其他CPU的二进制代码的执行顺序?
   哪些OS能保证?
   哪些OS不能保证?

3. 对于内核/驱动程序二进制代码,
   能否保证本CPU的二进制代码的执行顺序?
   能否保证其他CPU的二进制代码的执行顺序?

(执行次序,均为从store/load指令角度看到的指令执行结果次序)

论坛徽章:
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
60 [报告]
发表于 2011-10-18 16:54 |只看该作者
你猜对了,我确实不是。但我不认为这点可以作为后半句的论据。


本楼讨论的是"两语句的顺序是否有保 ...
OwnWaterloo 发表于 2011-10-18 16:42


这个不用争了, 属于两个问题, 如果能弄清楚确实发生了这种情况CPU如何动作, 才是对实质问题有助于加深理解的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP