int []数组上的并发读访问:它安全吗?它快吗?

时间:2009-02-17 11:22:48

标签: .net multithreading arrays multicore

在四核机器上,我正在考虑C#/ .NET算法的并行化,它涉及让多个线程同时读取小型int []数组。到目前为止,它似乎运行得相当好,但我不确定在哪里指定数组上的并发读取在.NET中是线程安全的。有什么指针吗?

然后,我也想知道这种方法是否真的有效?有没有你最好实际复制每个线程的输入数据的情况,这样就没有任何并发​​读取,并且每个数组(可能?)都有机会在亲和CPU附近缓存?

有关多核CPU的最佳实践的想法吗?

7 个答案:

答案 0 :(得分:18)

我不认为并发读取存在问题。但是,如果存在并发写入,则可能会出现问题。

不可变数据本质上是线程安全的。

答案 1 :(得分:11)

在您的情况下,并发读取您的数组将是线程安全的。

至于算法的有效性,根据数组的大小,如果它适合缓存,那么你可能会看到出色的性能提升,因为多核有效地“对抗”CPU中的缓存。如果他们正在努力用相同的信息填充缓存,他们将分享意味着更多的缓存命中和更好的性能。

假设您的阵列适合缓存......

答案 2 :(得分:4)

没有理由不同时读取数组的内容,假设内容永远不会改变。没有并发问题,因此无需复制。

我怀疑你能做些什么来让它更快。

答案 3 :(得分:3)

不应该打扰你。并发读取不是问题。任意数量的线程都可以同时读取相同的内存。

答案 4 :(得分:3)

如果.NET性能和并行性受到威胁,我建议尝试在F#中编写这个特定的算法。 F#编译器将生成.NET code that has 2-6 better performance

答案 5 :(得分:2)

更新数据时,线程安全只是一个问题。如果您有多个并发线程 正在更新 ,则必须在同步机制中包装更新(并且如果更新不是原子的,则读取更新)。对于只读数据结构,并发性不是问题。

答案 6 :(得分:1)

赋值运算符不是线程安全的。

这意味着如果您的线程只读取数组 - 如果数组在程序启动时初始化并且没有更改 - 那么您就是安全的。

但是,如果存在编写新值的作者,则您很容易受到竞争条件的影响。

基本问题是这个;读者开始读取整数。该值从内存加载到寄存器中。此时,读者交换掉了。然后,编写器更新内存中的值。然后读者重新接通并对他加载的值进行操作 - 这不再正确。

这意味着if()之类的内容无法可靠地运行。例如,

if( int_array[5] == 10 )
{
}

int_array[5]的内存中值不再为10时,可能会触发。

我相信C#,您应该可以访问Interlocked*()函数调用,例如InterlockedCompareAndSwap()。在这种情况下,这些将允许您轻松实现线程安全。