This topic has been archived. It cannot be replied.
-
工作学习 / 专业技术讨论 / 给大家出一个c++的问题。我以前这样考虑过,然后写了一个程序验证了一下,得到了答案。在32位cpu上,多个thread对int 全局变量做++,如g_i++,这个变量没有用critical section保护。由于是整数刚好是32位,cpu可以一次完成++操作,所以不保护也不会发生任何错误。如果是__int64变量,就需要保护。但如果在64位cpu上,__int64也不需要保护。
我的问题是这个想法是对的吗?
如果对,为什么?不对,又为什么?
-toronto_fun(BeMyself);
2006-4-17
{302}
(#2911099@0)
-
wrong. read-add-write can be broken.
-iwantcar(EnjoyStudying);
2006-4-18
(#2911861@0)
-
除非你声明变量是register变量,如果不是register变量不行。i++ 一般会翻译成2条指令mov (mem) to reg; inc (reg).而且就是声明成register变量,也不能保证就一定是register。所以一般而言, no.
-canadiantire(轮胎-M.I.N.K.);
2006-4-18
(#2911955@0)
-
Not completely right. Even if it is register, not ok either. because there may be SMP, etc. By the way, have you ever share register between threads? In that case, the register that is not the adder may cause problem.
-iwantcar(EnjoyStudying);
2006-4-18
(#2912363@0)
-
这个肯定错误!
因为一个简单的++操作也要由三条指令完成,
1 mov eax, [1234]
2 add eax, 1
3 move [1234], eax
[1234]为那个变量的地址。
所以在多线程环境中,如果不保护肯定会出错。
如果使用register,也一样是三条指令。
通过汇编代码一看就明白了,谢谢大家!
-toronto_fun(BeMyself);
2006-4-18
{241}
(#2913221@0)
-
“所以不保护也不会发生任何错误“” -- 您说的错误是指什么呢?
-aka(棒棒);
2006-4-19
(#2915395@0)
-
up 之!
-aka(棒棒);
2006-4-20
(#2917854@0)
-
我记得X86汇编指令有对地址加1的,好象是inc word ptr:Val. 着是一条指令不会被打断. 估计你写的g_j++是变成这样了.
-ai97(温酒吧地爱板);
2006-4-19
(#2916115@0)
-
Please don't guess.
-iwantcar(EnjoyStudying);
2006-4-20
(#2916140@0)
-
没错,x86汇编加法指令支持内存+立即数,内存+寄存器之间的操作:add [var], 1或者mov eax,1 add [var], eax. 使用这2种方法就可以保证DWORD加法是atom operation。但是不知道c有没有编译选项可以强制使用这2种方法.想用总是有办法的,大不了c里夹着汇编。
-baalinca(scarb);
2006-4-20
{38}
(#2916401@0)
-
SMP.
-iwantcar(EnjoyStudying);
2006-4-20
(#2916411@0)
-
什么意思?编译选项
-baalinca(scarb);
2006-4-20
(#2916490@0)
-
http://en.wikipedia.org/wiki/Symmetric_multiprocessing
-iwantcar(EnjoyStudying);
2006-4-20
(#2916538@0)
-
Not like that. It's depending on hardware but depending on your compiler, libraries and maybe OS as well. There are dfferent definitions of atomic operations.
-ccloafer(梦游加拿大);
2006-4-20
(#2916408@0)
-
一条机器码执行期间不能被中断,这应该对所有的系统都适用吧?
-baalinca(scarb);
2006-4-20
(#2916455@0)
-
http://en.wikipedia.org/wiki/Symmetric_multiprocessing
-iwantcar(EnjoyStudying);
2006-4-20
(#2916539@0)
-
SMP..., as only one processor can access memory at a time; NUMA ... allows processors to access memory in parallel, ... if the data is localized to specific processes.NUMA... dedicates different memory banks to different processors. 言而总之,内存存取是串行的
-baalinca(scarb);
2006-4-20
{92}
(#2916635@0)
-
But you need to read-add-write, I mean in the memory bus.
-iwantcar(EnjoyStudying);
2006-4-20
(#2916692@0)
-
硬件必须保证单个cpu指令是原子操作,否则OS怎么实现mutex。
-baalinca(scarb);
2006-4-20
(#2916811@0)
-
Lock the bus, guy, read the processor manual please, it is not only about the intruction
-iwantcar(EnjoyStudying);
2006-4-20
(#2917087@0)
-
For some processor, there is a special instruction that can do mutex. But this is not mathematical operation instruction.
-iwantcar(EnjoyStudying);
2006-4-20
(#2917092@0)
-
We are talking about C++, not assembly language for bare machine. To be interrupt is not necessarily to be protected. Otherwise, you have to put interruptDisable before and interruptEnable after each operation.However, in most cases things are you have to protect a lot of things because of multithreading not because of interrupt.
-ccloafer(梦游加拿大);
2006-4-20
{121}
(#2916798@0)
-
我其实是想说:一条机器指令可能包含读/操作/写但它是最小单元,不可再分割,是原子操作。我说的中断不仅仅是可以被屏蔽的外部硬件中断。
-baalinca(scarb);
2006-4-20
(#2916853@0)
-
wrong.
-iwantcar(EnjoyStudying);
2006-4-20
(#2917436@0)
-
你说的是对的。一条机器指令是原子操作只适用单cpu
-baalinca(scarb);
2006-4-20
(#2917680@0)
-
SMP, 也能保证数据完整, 所有的CPU在访问某个地址前,都要查询其他的CPU是不是在读写着个地址, 这过程叫snoop. 如果是就等, snoop会通知那个CPU释放这个地址, 写回内存去.
-ai97(温酒吧地爱板);
2006-4-20
(#2917692@0)
-
wrong! no matter it's 32/64 or single/SMP/dual core register or not.
-steven99ca(Don);
2006-5-9
(#2957966@0)
-
这个没问题的,程序肯定不会CRASH,只是计数器可能不太准确,不过误差很小的。如果不是很重要的统计数据,没关系
-henryxy(亨利之重出江湖);
2006-5-10
(#2959150@0)
-
Are you kidding? If not, you really don't know What are you talking about
-steven99ca(Don);
2006-5-10
(#2959566@0)