免费注册 查看新帖 |

Chinaunix

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

对int变量的赋值是原子操作吗? [复制链接]

论坛徽章:
0
61 [报告]
发表于 2006-08-10 20:41 |只看该作者
原帖由 isjfk 于 2006-8-10 08:41 发表

机器指令总是具有原子性的,不可能被中断(除非断电或者硬件设计问题)。

前面不是有人说, INC/DEC/ADD 指令不是原子的吗?

论坛徽章:
0
62 [报告]
发表于 2006-08-10 20:44 |只看该作者
原帖由 isjfk 于 2006-8-10 08:55 发表

不用什么程序,看看 Intel CPU datasheet 的时序图就可以理解。而且如果没有逻辑分析仪,用GDB这样的调试器也无法理想的调试“数据没有对齐”的情况。



能否,详细根据 Intel CPU datasheet 来说明一下呢

论坛徽章:
0
63 [报告]
发表于 2006-08-11 10:02 |只看该作者
TO isjfk,

哈。你不要这样生气吗。对我来说 x86 就代表整个世界,我的见识的确很短浅。

但是我将这个问题的实质说明了,到底为什么是原子的,为什么不是原子的。然后大家可以讨论搞清楚。而一开始你连这一点问题的关键都不懂。根据你立即的回贴可以看出来。你说一个 int 赋值就会编译成好几条汇编语句就不原子了,这是起码的常识错误呀。说明你对进程(THREAD)切换,环境保存恢复的知识很少(但你对硬件,但片机等,肯定水平很高),所以才说出这样的话。int 赋值就会编译成好几条汇编语句和原子性没有关系。

恕我直言。

原帖由 isjfk 于 2006-8-4 09:35 发表
C 里面没有原子的概念吧,应该是平台相关的。至少在 51 单片机上面,一个 int 赋值就会编译成好几条汇编语句。

这个世界上正在使用的 CPU 不只是 x86,除非有人能够拿出证据证明所有的 CPU 体系结构上的 C 编译器编译出来的整形赋值其机器码都是原子操作,否则就不能作这样的假设。不要拿“常用的 CPU 都是原子的”作反驳,lz 并没有把问题局限在“常用的 CPU”上面。或许对你来说 x86 就代表整个世界,但是对于很多用单片机工作的人来说,51、AVR、PIC 远远要比 x86 亲切得多。我为什么不能用单片机举例?C 又不是 x86 的私有玩物

论坛徽章:
0
64 [报告]
发表于 2006-08-11 11:03 |只看该作者
原帖由 思一克 于 2006-8-11 10:02 发表
TO isjfk,

哈。你不要这样生气吗。对我来说 x86 就代表整个世界,我的见识的确很短浅。

但是我将这个问题的实质说明了,到底为什么是原子的,为什么不是原子的。然后大家可以讨论搞清楚。而一开始你连这一点 ...

...我看是得解释一下

首先我说说“至少在 51 单片机上面,一个 int 赋值就会编译成好几条汇编语句”这句话什么意思。51 单片机的寄存器是 8 位的,但是 C51 的 int 长度是 16 位。这就意味着一个 int 型的赋值(在未经优化的情况下)需要四条汇编指令:(由于年代久远,我已经记不清 51 的汇编怎么写了,就用伪码说明一下。PS:我的硬件水平很低其实,也就可以骗一骗菜鸟 。看什么看,说你呢,刚才谁说我硬件水平很高来着

  1. mov    a, 源第一个字节
  2. mov    目的第一个字节, a
  3. mov    a, 源第二个字节
  4. mov    目的第二个字节, a
复制代码

也就是说一次 int 的赋值对应 4 条机器指令。因为寄存器长度的关系,一个 int 赋值需要分段进行。我的意思不在于一个 int 赋值最终被编译成几条机器指令,而是对数据的操作是否是整体的。如果不能进行整体的操作显然就需要多条机器指令。这个是我前面没有考虑到这句话可以理解为“先装载到寄存器,再存储到内存两条指令”的意思。

后面的论战由此而来,我看就不用再解释了。

每条机器指令都是原子操做,所以对于 lz 的问题,本质就归结于 CPU 对于 int 类型长度的数据能否进行整体的操做。如果不能或者不是总能,那就不是原子的。我记得前面说过类似的话。

算啦,我看别再打架了。大家都是读书人,君子动手不动口~


其实我是先学明白的汇编语言、数据结构、操作系统原理这些东西才去搞了一段时间硬件,只是因为觉得好玩。现在感觉这一段经历对我的观念影响真的挺大。

[ 本帖最后由 isjfk 于 2006-8-11 11:08 编辑 ]

论坛徽章:
0
65 [报告]
发表于 2006-08-11 11:07 |只看该作者
原帖由 mik 于 2006-8-10 20:44 发表

能否,详细根据 Intel CPU datasheet 来说明一下呢

呵呵,前面我大脑充血说了一些不负责任的话,其实是没经过考证的。回头我看看 Intel CPU 的指令时序图和中断处理时序图,现在手上没资料。

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
66 [报告]
发表于 2006-08-11 12:02 |只看该作者
原帖由 思一克 于 2006-8-11 10:02 发表
int 赋值就会编译成好几条汇编语句和原子性没有关系。点 ...


能解释下为什么没关系吗?

论坛徽章:
0
67 [报告]
发表于 2006-08-11 12:11 |只看该作者
比如一个C复制被搞成了5行汇编,
只要最后的一个是整体(整数)复制就可以了。分成100行汇编也没有关系。因为进程调度会保留环境,再运行时接着走。

只有当一个C 整数复制被分字节做,那才有关系。但除了能力十分有限的单片CPU,好象没有这样的。

这个问题不是绝对的。一般是对于一般CPU,单CPU机器说的。

论坛徽章:
0
68 [报告]
发表于 2006-08-11 12:28 |只看该作者
原帖由 思一克 于 2006-8-11 12:11 发表
只有当一个C 整数复制被分字节做,那才有关系。但除了能力十分有限的单片CPU,好象没有这样的。

不止是“能力十分有限的单片CPU”吧,我怎么记得有些能力非常强的 CPU 要求对内存数据的操作必须是在对齐的地址上,不对齐的数据需要在程序里分次读入,而不像 x86 那样为程序员着想...

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
69 [报告]
发表于 2006-08-11 12:29 |只看该作者
>>>b = a;
movl a, %eax  //1
movl %eax, b  //2

1,2之间发生中断,会发生不一致。
b = a;被分开了,何来原子?
int是高级语言中的概念,所以"int变量赋值"不是原子的。
OS理论书籍的分析中是把这些基本C语句作为整体来简化讨论的。就像复杂性分析时把这些语句看成O(1)是一样的。
原子性只存在于指令集代码中。在原子性和一致性中,软件方法只能保证一致性(虽然绝大部分机器用机器指令实现一致性功能而不是软件),不能保证原子性。
任意两条指令集代码之间都有可能会被中断。这也是总线锁定指令lock需要存在的原因之一。

论坛徽章:
0
70 [报告]
发表于 2006-08-11 12:31 |只看该作者
To jsjfk,

对齐的问题我也知道。在linux的众多atomic.h中就可以看到。
我一开始就建议去看这些文件。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP