这是一个复杂的问题,请考虑清楚之前回答。

考虑这种情况。两个螺纹(a读者和作家)的接入一个单一的全球性 int.这安全吗?通常情况下,我将作出回应没有思想,是的!

然而,在我看来,草萨特不这么认为。在他的文章在有效的并发他讨论了一个 有缺陷的无锁队列修正版本.

在结束第一条和开始第二,他讨论了一个很少考虑特征的变量,编写订购。Int的是原子的,好的,但整数并不一定命令,它可以摧毁任何无锁算法,包括我的上述情形。我完全同意的唯一方法 保证 正确的多线程的行为的所有平台上现在和未来是使用用原子公司(又名记忆障碍)或互斥体。

我的问题;是写重新odering问题上的真正的硬件?或是多线程的偏执狂就是迂腐的?
什么经典的单处理器系统?
怎么样简单RISC处理器像一个嵌入电-电脑?

澄清:我更感兴趣什么先生萨特说,有关硬件(处理器/cache)重新排序变量写入。我可以阻止优化程序,从破码编译器或手工检查的大会后汇编。但是,我想知道如果硬件仍然可以弄乱的代码,在实践中。

有帮助吗?

解决方案

你检查装配的想法不够好;重新排序可以在硬件级别进行。

要回答你的问题<!>“这是读取硬件上的一个问题:<!>”; 是的!事实上我自己遇到了这个问题。

可以解决单处理器系统或其他特殊情况下的问题吗?我认为<!>“;没有<!>”;因为从现在起五年后你可能需要在多核上运行,然后找到所有这些位置将是棘手的(不可能?)。

一个例外:为嵌入式硬件应用程序设计的软件确实可以完全控制硬件。事实上,我有<!>“被欺骗的<!>”;在这种情况下,例如ARM处理器。

其他提示

是的 - 使用内存屏障来防止在需要时重新排序指令。在一些C ++编译器中,volatile关键字已经扩展为每次读写都插入了隐式内存屏障 - 但这不是一个可移植的解决方案。 (与Interlocked * win32 API类似)。 Vista甚至添加了一些新的细粒度互锁API,允许您指定读或写语义。

不幸的是,C ++有一个松散的内存模型,任何类似的代码在某种程度上都是不可移植的,你必须为不同的平台编写不同的版本。

就像你说的那样,由于在缓存或处理器级别进行重新排序,你实际上确实需要某种内存屏障来确保正确的同步,特别是对于多处理器(尤其是非x86平台)。 (我相信单处理器系统没有这些问题,但是不要引用我的话 - 我当然更倾向于安全地进行同步访问。)

我们遇到了这个问题,尽管在Itanium处理器上,指令重新排序比x86 / x64更具攻击性。

修复是使用Interlocked指令,因为当时(当时)没有办法告诉编译器只是简单但是在赋值后写入屏障。

我们真的需要语言扩展来干净利落地处理这个问题。对于你试图从一段代码中尽可能多地提高性能的情况来说,使用volatile(如果编译器支持的话)太粗糙了。

是这个问题上真正的硬件?

绝对,特别是现在移动到多个核于当前和未来的Cpu。如果你依赖上订购原子性,以实现功能的应用程序和你都无法保证这一要求通过你选择的平台或使用同步元下 所有 条件,即客户从一个单一的核CPU多核CPU,然后你只是在等待一个问题的发生。

引用自称草Sutter条(第二个)

订购原子变量阐明在不同的方式在普遍的平台和环境。例如:

  • volatile 在C#/.净,因为在 volatile int.
  • volatile 或*原子*在爪哇,作为在 volatile int, AtomicInteger.
  • atomic<T> C++0x,即将举行的ISO C++的标准,因为在 atomic<int>.

我还没有看到如何C++0x实现有序原子性所以我无法说明是否即将到来的语言功能是一个纯粹的图书馆实施,或依赖对改变语言。你可以审查该提案,看看它是否可以被合并为一个非标准扩展到你的当前工具链,直到新的标准是可用的,它甚至可能已经对您的情况。

这是真实硬件上的问题。我的一个朋友为IBM工作,主要是通过在客户的代码中解决这类问题来谋生。

如果你想看看事情有多糟糕,可以在Java Memory Model(以及现在的C ++内存模型)上搜索学术论文。鉴于真实硬件可以做的重新排序,试图弄清楚高级语言中的安全性是一场噩梦。

这不是安全的,并且存在显示此问题的真实硬件,例如xbox 360上的powerpc芯片中的内存模型允许重新排序写入。由于内在函数缺乏障碍而加剧了这种情况,请参阅 msdn 了解更多详情。

问题的答案<!>“;是安全的<!>本质上是模棱两可的。

即使对于双打来说,它总是安全的,因为你的计算机不会着火。 这是安全的,从某种意义上说,你总是会获得过去某个时间int所持有的值, 它是不安全的,因为你可能得到一个值,它将被另一个线程更新。

<!>

QUOT;原子QUOT <!>;意味着你得到第二个保证。由于double通常不是原子的,因此可以得到32个旧位和32个新位。这显然是不安全的。

当我问到我对单处理器powerpc最感兴趣的问题时。在其中一条评论中, InSciTek Jeff 提到了powerpc SYNC和ISYNC指令。那些确定答案的关键。我在IBM的网站上找到了它这里

这篇文章很大而且非常密集,但带走的是不,这是不安全的。在旧的powerpc上,内存优化器不够复杂,不会在单处理器上造成问题。但是,较新的那些更具攻击性,甚至可以打破对全局int的简单访问。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top