This question already has an answer here:
这个问题在这里已有答案:
- Are C# arrays thread safe? 4 answers
C#数组是否安全? 4个答案
Lets say we have an array of two element which are type of some primitive value.
假设我们有一个包含两个元素的数组,它们是一些原始值的类型。
volatile int[] a = new int[2]{0,0};
I have two threads, each of them writes/reads one of the elements. First thread works only with a[0] and second thread works only with a[1].
我有两个线程,每个线程都写入/读取其中一个元素。第一个线程仅适用于[0],第二个线程仅适用于[1]。
Can array be worked this way, or array is still required to be locked, even if different index values are being affected?
可以通过这种方式处理数组,或者仍然需要锁定数组,即使不同的索引值受到影响吗?
1 个解决方案
#1
3
A thread does not need to issue a lock on a memory location that is not used by any other thread. So in your case, a lock
statement would be unnecessary.
线程不需要在任何其他线程未使用的内存位置上发出锁定。所以在你的情况下,锁定语句是不必要的。
That being said, there is a CPU cache lock you should worry about. If a[0]
and a[1]
both fall within the same 64-byte block, they will share a cache line, meaning that each CPU core will try to load that block of memory into onboard cache, locking out any other CPU cores. If this happens, only one of your threads can access those variables at a time, and any other threads will block until the cache is pushed back to main memory and the lock is released. This problem, known as false sharing, will throttle your performance, making a multi-threaded approach perform no better, and possibly worse, than a single-threaded solution. There is no way to turn off this lock, although you could avoid it by spacing your variables out in memory so they fall within different 64-byte blocks.
话虽这么说,你应该担心CPU缓存锁定。如果[0]和[1]都属于同一个64字节块,它们将共享一个缓存行,这意味着每个CPU内核将尝试将该内存块加载到板载缓存中,锁定任何其他CPU内核。如果发生这种情况,一次只有一个线程可以访问这些变量,并且任何其他线程都会阻塞,直到缓存被推回到主内存并释放锁。这个称为错误共享的问题将限制您的性能,使多线程方法的性能不比单线程解决方案好,甚至可能更差。没有办法关闭这个锁,虽然你可以通过将变量在内存中间隔开来避免它,因此它们属于不同的64字节块。
(64-byte is based on modern Wintel... your experience may vary)
(64字节基于现代Wintel ......您的体验可能会有所不同)
#1
3
A thread does not need to issue a lock on a memory location that is not used by any other thread. So in your case, a lock
statement would be unnecessary.
线程不需要在任何其他线程未使用的内存位置上发出锁定。所以在你的情况下,锁定语句是不必要的。
That being said, there is a CPU cache lock you should worry about. If a[0]
and a[1]
both fall within the same 64-byte block, they will share a cache line, meaning that each CPU core will try to load that block of memory into onboard cache, locking out any other CPU cores. If this happens, only one of your threads can access those variables at a time, and any other threads will block until the cache is pushed back to main memory and the lock is released. This problem, known as false sharing, will throttle your performance, making a multi-threaded approach perform no better, and possibly worse, than a single-threaded solution. There is no way to turn off this lock, although you could avoid it by spacing your variables out in memory so they fall within different 64-byte blocks.
话虽这么说,你应该担心CPU缓存锁定。如果[0]和[1]都属于同一个64字节块,它们将共享一个缓存行,这意味着每个CPU内核将尝试将该内存块加载到板载缓存中,锁定任何其他CPU内核。如果发生这种情况,一次只有一个线程可以访问这些变量,并且任何其他线程都会阻塞,直到缓存被推回到主内存并释放锁。这个称为错误共享的问题将限制您的性能,使多线程方法的性能不比单线程解决方案好,甚至可能更差。没有办法关闭这个锁,虽然你可以通过将变量在内存中间隔开来避免它,因此它们属于不同的64字节块。
(64-byte is based on modern Wintel... your experience may vary)
(64字节基于现代Wintel ......您的体验可能会有所不同)