C ++ 0x MM和其他MM之间的细微差别 [英] Subtle difference between C++0x MM and other MMs
问题描述
考虑遵循Peterson在维基百科上的算法实现:
http://en.wikipedia.org/wiki/Peterson%27s_algorithm
flag [0] = 0
flag [1] = 0
转= 0
P0:flag [0] = 1
turn = 1
memory_barrier()
while(flag [1]&& turn == 1);
//什么都不做
//关键部分
...
//关键部分结束
flag [0] = 0
P1:flag [1] = 1
turn = 0
memory_barrier()
while(flag [0]&& ;转== 0);
//什么都不做
//关键部分
...
//临界区结束
flag [1] = 0
我们可以使用volatile变量在Java中实现这一点,并且需要
memory_barrier()将由编译器自动发出br />
我们可以使用volatile变量在C#中实现这个,并且
Thread.MemoryBarrier()作为memory_barrier()。
我们可以在x86中实现这个MM使用普通的加载和存储,并使用
mfence指令作为memory_barrier()。
我们可以使用std :: atomic<和发布加载<在C ++ 0x中实现它br />
使用memory_order_acquire,使用memory_order_release存储,以及
atomic_thread_fence(memory_order_seq_cst)作为memory_barrier()。这是$ / b $ b最简单的Java / C#/ x86实现转换。
唯一的问题是C ++ 0x实现不起作用。 />
就我个人而言,这是违反直觉的。以下
问题出现了。将一些现有的/ b $ b Java / C#/ x86算法实现转换为C ++ 0x的最简单方法是什么?好像它不是那么简单......
Dmitriy V''jukov
Consider following Peterson''s algorithm implementation from Wikipedia:
http://en.wikipedia.org/wiki/Peterson%27s_algorithm
flag[0] = 0
flag[1] = 0
turn = 0
P0: flag[0] = 1
turn = 1
memory_barrier()
while( flag[1] && turn == 1 );
// do nothing
// critical section
...
// end of critical section
flag[0] = 0
P1: flag[1] = 1
turn = 0
memory_barrier()
while( flag[0] && turn == 0 );
// do nothing
// critical section
...
// end of critical section
flag[1] = 0
We can implement this in Java using volatile variables, and needed
memory_barrier() will be emitted automatically by compiler.
We can implement this in C# using volatile variables, and
Thread.MemoryBarrier() as memory_barrier().
We can implement this in x86 MM using plain loads and stores, and
mfence instruction as memory_barrier().
We can implement this in C++0x using std::atomic<and issuing loads
with memory_order_acquire, stores with memory_order_release, and
atomic_thread_fence(memory_order_seq_cst) as memory_barrier(). This is
the most straightforward translation of Java/C#/x86 implementations.
The only problem is that C++0x implementation will not work.
Personally for me, it''s quite counter-intuitive. And following
question arise. What is the most simple way to translate some existing
Java/C#/x86 algorithm implementation to C++0x? It seems that it''s not
so easy...
Dmitriy V''jukov
推荐答案
8月24日,7:46 * pm,Dmitriy V''jukov < dvyu ... @ gmail.comwrote:
On Aug 24, 7:46*pm, "Dmitriy V''jukov" <dvyu...@gmail.comwrote:
考虑遵循Peterson在维基百科上的算法实现: http://en.wikipedia.org/wiki/Peterson%27s_algorithm
* flag [0] * = 0
* flag [1] * = 0
* turn * * * = 0
* P0:flag [0] = 1
* * turn = 1
* * memory_barrier()
* * while(flag [1]&& turn == 1);
* * * * * * //什么都不做
* * //关键部分
* * ...
* * //关键部分结束
* * flag [0] = 0
P1:flag [1] = 1
* * turn = 0
* * memory_barrier()
* * while(flag [ 0]&&转= = 0);
* * * * * * //什么都不做
* * //关键部分
* * ...
* * //关键部分结束
* * flag [1] = 0
我们可以使用volatile变量在Java中实现它,并且需要
memory_barrier()将由编译器自动发出。
Consider following Peterson''s algorithm implementation from Wikipedia:http://en.wikipedia.org/wiki/Peterson%27s_algorithm
*flag[0] * = 0
*flag[1] * = 0
*turn * * *= 0
*P0: flag[0] = 1
* * turn = 1
* * memory_barrier()
* * while( flag[1] && turn == 1 );
* * * * * * // do nothing
* * // critical section
* * ...
* * // end of critical section
* * flag[0] = 0
P1: flag[1] = 1
* * turn = 0
* * memory_barrier()
* * while( flag[0] && turn == 0 );
* * * * * * // do nothing
* * // critical section
* * ...
* * // end of critical section
* * flag[1] = 0
We can implement this in Java using volatile variables, and needed
memory_barrier() will be emitted automatically by compiler.
和C ++相当的是使用seq_cst加载和存储,它们相当于Java volatiles的
。
And the C++ equivalent is to use seq_cst load and stores, which are
equivalent to Java volatiles.
我们可以使用volatile变量在C#中实现这个,并且
Thread.MemoryBarrier()作为memory_barrier()。
我们可以实现这个在x86 MM中使用普通加载和存储,并使用
mfence指令作为memory_barrier()。
我们可以使用std :: atomic<并在发布时在C ++ 0x中实现它使用memory_order_acquire加载
,使用memory_order_release存储,并将
atomic_thread_fence(memory_order_seq_cst)作为memory_barrier()。这是对Java / C#/ x86实现最直接的翻译。
唯一的问题是C ++ 0x实现不起作用。
We can implement this in C# using volatile variables, and
Thread.MemoryBarrier() as memory_barrier().
We can implement this in x86 MM using plain loads and stores, and
mfence instruction as memory_barrier().
We can implement this in C++0x using std::atomic<and issuing loads
with memory_order_acquire, stores with memory_order_release, and
atomic_thread_fence(memory_order_seq_cst) as memory_barrier(). This is
the most straightforward translation of Java/C#/x86 implementations.
The only problem is that C++0x implementation will not work.
为什么它不起作用?
Why will it not work?
24á×?,21:52,Peter Dimov< ; pdi ... @ gmail.comwrote:
On 24 á×?, 21:52, Peter Dimov <pdi...@gmail.comwrote:
8月24日晚上7:46,Dmitriy V''jukov < dvyu ... @ gmail.comwrote:
On Aug 24, 7:46 pm, "Dmitriy V''jukov" <dvyu...@gmail.comwrote:
考虑遵循Peterson在维基百科上的算法实现: http://en.wikipedia.org/wiki/Peterson%27s_algorithm
flag [0] = 0
flag [1] = 0
turn = 0
flag[0] = 0
flag[1] = 0
turn = 0
P0:flag [0] = 1
turn = 1
memory_barrier()
while(flag [1] &&转= = 1);
//什么都不做
//关键部分
...
//关键部分结束
flag [0] = 0
P0: flag[0] = 1
turn = 1
memory_barrier()
while( flag[1] && turn == 1 );
// do nothing
// critical section
...
// end of critical section
flag[0] = 0
P1:flag [1] = 1
转= 0
memory_barrier()
while(flag [0]&& turn == 0);
//什么都不做
//关键部分
...
//关键部分结束
flag [1] = 0
P1: flag[1] = 1
turn = 0
memory_barrier()
while( flag[0] && turn == 0 );
// do nothing
// critical section
...
// end of critical section
flag[1] = 0
我们可以使用volatile变量在Java中实现这个,并且需要
memory_barrier()将是由编译器自动发出。
We can implement this in Java using volatile variables, and needed
memory_barrier() will be emitted automatically by compiler.
和C ++相当的是使用seq_cst加载和存储,它们相当于Java volatiles的
。
And the C++ equivalent is to use seq_cst load and stores, which are
equivalent to Java volatiles.
是的,可以使用seq_cst原子实现任何依赖于C ++ 0x中的
顺序一致内存模型的算法
操作。但! Seq_cst原子操作,尤其是商店,可能相当昂贵。因此,人们普遍希望使用较弱的操作,
,如存储释放和负载获取。在Java / C#/ x86中,使用弱操作+ 1强
栅栏来实现Peterson的算法是可能的。在C ++ 0x - NOT。
Yes, it''s possible to implement any algorithm that relying on
sequentially consistent memory model in C++0x using seq_cst atomic
operations. But! Seq_cst atomic operations, especially stores, can be
quite expensive. So, one has general desire to use weaker operations,
like store-release and load-acquire. And in Java/C#/x86 it''s possible
to implement Peterson''s algorithm using weak operations + 1 strong
fence. In C++0x - NOT.
我们可以使用volatile变量在C#中实现它,并且
Thread.MemoryBarrier()as memory_barrier()。
我们可以使用普通的加载和存储在x86 MM中实现这个,并使用
mfence指令作为memory_barrier( )。
我们可以使用std :: atomic<在C ++ 0x中实现它,并使用memory_order_acquire发布负载
,使用memory_order_release存储,以及
atomic_thread_fence(memory_order_seq_cst)作为memory_barrier()。这是对Java / C#/ x86实现最直接的翻译的
。
We can implement this in C# using volatile variables, and
Thread.MemoryBarrier() as memory_barrier().
We can implement this in x86 MM using plain loads and stores, and
mfence instruction as memory_barrier().
We can implement this in C++0x using std::atomic<and issuing loads
with memory_order_acquire, stores with memory_order_release, and
atomic_thread_fence(memory_order_seq_cst) as memory_barrier(). This is
the most straightforward translation of Java/C#/x86 implementations.
唯一的问题是C ++ 0x实现不起作用。
The only problem is that C++0x implementation will not work.
为什么它不起作用?
Why will it not work?
我的意思不是彼得森算法的每个C ++ 0x实现,而是
使用存储释放,加载的特定实现-acquire + 1
seq_cst围栏。
Dmitriy V''jukov
I mean not every C++0x implementation of Peterson''s algorithm, but
particular implementation which uses store-release, load-acquire + 1
seq_cst fence.
Dmitriy V''jukov
8月24日,9:44 * pm,Dmitriy V''jukov < dvyu ... @ gmail.comwrote:
On Aug 24, 9:44*pm, "Dmitriy V''jukov" <dvyu...@gmail.comwrote:
在Java / C#/ x86中,实现Peterson可能需要
'算法使用弱操作+ 1强
围栏。在C ++ 0x - NOT。
And in Java/C#/x86 it''s possible
to implement Peterson''s algorithm using weak operations + 1 strong
fence. In C++0x - NOT.
如何使用弱的
操作和围栏实现Peterson的Java算法? Java没有弱操作或围栏。
它的易变性加载和存储相当于C ++ MM的seq_cst加载
和商店。两者都承诺顺序一致性(不多也不少)。
How would you implement Peterson''s algorithm in Java using weak
operations and a fence? Java doesn''t have weak operations or fences.
Its volatile loads and stores are equivalent to C++MM''s seq_cst loads
and stores. Both promise sequential consistency (no more and no less).
我的意思不是彼得森算法的每个C ++ 0x实现,而是
使用store-release,load-acquire + 1
seq_cst fence的特定实现。
I mean not every C++0x implementation of Peterson''s algorithm, but
particular implementation which uses store-release, load-acquire + 1
seq_cst fence.
为什么你认为这个实现不起作用?
Why do you think that this implementation doesn''t work?
这篇关于C ++ 0x MM和其他MM之间的细微差别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!