Interlocked.Exchange 和 Volatile.Write 之间的区别? [英] difference between Interlocked.Exchange and Volatile.Write?

查看:35
本文介绍了Interlocked.Exchange 和 Volatile.Write 之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Interlocked.Exchange 和 Volatile.Write 有什么区别?

What is the difference between Interlocked.Exchange and Volatile.Write?

这两种方法都会更新某个变量的值.有人可以总结一下何时使用它们吗?

Both methods update value of some variable. Can someone summarize when to use each of them?

http://msdn.microsoft.com/ru-ru/library/bb337971http://msdn.microsoft.com/en-us/library/gg712713.aspx

特别是我需要更新我的数组的双项,我希望另一个线程看到最新的值.什么是首选?Interlocked.Exchange(ref arr[3], myValue)Volatile.Write(ref arr[3], info); 其中 arr 是声明为 double?

In particular I need to update double item of my array, and I want another thread to see the freshest value. What is preferred? Interlocked.Exchange(ref arr[3], myValue) or Volatile.Write(ref arr[3], info); where arr is declared as double?

============================================================================真实的例子,我像这样声明双数组:

============================================================================ Real example, I declare double array like that:

private double[] _cachedProduct;

在一个线程中,我像这样更新它:

In one thread I update it like that:

        _cachedProduct[instrumentId] = calcValue;
        ...
        are.Set();

在另一个线程中,我像这样读取了这个数组:

In another thread I read this array like that:

        while(true) {
            are.WaitOne();
            ...
                result += _cachedProduct[instrumentId];
            ...
        }

对我来说,它按原样运行良好.但是,无论看起来如何,为了确保它始终有效",我应该添加 Volatile.WriteInterlocked.Exchange.因为不保证双重更新是原子的 http://msdn.microsoft.com/en-us/library/aa691278%28VS.71%29.aspx

For me it just works fine as is. However to make sure "it will always work" no matter what it seems I should add either Volatile.Write or Interlocked.Exchange. Because double update is not guaranted to be atomic http://msdn.microsoft.com/en-us/library/aa691278%28VS.71%29.aspx

在这个问题的答案中,我想看到 Volatile 和 Interlocked 类的详细比较.为什么我们需要 2 个班级?使用哪一种以及何时使用?

In the answer to this question I want to see detailed comparision of Volatile and Interlocked classes. Why we need 2 classes? Which one and when to use?

推荐答案

Interlocked.Exchange 使用保证原子操作的处理器指令.

the Interlocked.Exchange uses a processor instruction that guarantees an atomic operation.

Volatile.Write 执行相同的操作,但它还包括内存屏障操作.我认为微软在 DotNet 4.5 上添加了 Volatile.Write,因为它支持 Windows 8 上的 ARM 处理器.英特尔和 ARM 处理器在内存操作重新排序上有所不同.

The Volatile.Write does the same but it also includes a memory barrier operation. I think Microsoft added Volatile.Write on DotNet 4.5 due to support of ARM processors on Windows 8. Intel and ARM processors differs on memory operation reordering.

在 Intel 上,您可以保证内存访问操作将按照它们发出的相同顺序完成,或者至少不会重新排序写入操作.

On Intel, you have a guarantee that memory access operations will be done in the same order they are issued, or at least that a write operation won't be reordered.

来自英特尔® 64 位和 IA-32 架构软件开发人员手册,第 8 章:

From Intel® 64 and IA-32 Architectures Software Developer’s Manual, Chapter 8:

8.2.2 P6 和更多最新处理器系列中的内存订购英特尔酷睿 2 Duo、英特尔凌动、英特尔酷睿双核、奔腾 4 和 P6 系列处理器还使用处理器排序的内存排序模型,该模型可以进一步定义为使用存储缓冲区转发进行写入排序".该模型的特点如下.

8.2.2 Memory Ordering in P6 and More Recent Processor Families The Intel Core 2 Duo, Intel Atom, Intel Core Duo, Pentium 4, and P6 family processors also use a processor-ordered memory-ordering model that can be further defined as "write ordered with store-buffer forwarding." This model can be characterized as follows.

在 ARM 上,您没有这种保证,因此需要内存屏障.可以在此处找到解释这一点的 ARM 博客:http://blogs.arm.com/software-enablement/594-memory-access-ordering-part-3-memory-access-ordering-in-the-arm-架构/

On ARM you don't have this kind of guarantee, so a memory barrier is required. An ARM blog explaining this can be found here: http://blogs.arm.com/software-enablement/594-memory-access-ordering-part-3-memory-access-ordering-in-the-arm-architecture/

在您的示例中,由于不能保证使用 double 的操作是原子的,因此我建议使用锁来访问它.请记住,在读取和设置值时,您必须对代码的两部分都使用锁.

In your example, as the operation with double is not guaranteed to be atomic, I would recommend a lock to access it. Remember that you have to use the lock on both parts of your code, when reading and setting the value.

一个更完整的例子会更好地回答你的问题,因为不清楚设置这些值后会发生什么.对于向量,如果读者多于作者,请考虑使用 ReaderWriterLockSlim 对象:http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

A more complete example would be better to answer your question, as it is not clear what happens after these values are set. For a vector, if you have more readers than writers, consider the use of a ReaderWriterLockSlim object: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

线程数和读/写频率会显着改变您的锁定策略.

The number of threads and the frequency of read/writes can change dramatically your locking strategy.

这篇关于Interlocked.Exchange 和 Volatile.Write 之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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