C ++ 0x MM和其他MM之间的细微差别 [英] Subtle difference between C++0x MM and other MMs

查看:62
本文介绍了C ++ 0x MM和其他MM之间的细微差别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑遵循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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆