Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net int[]数组上的并发读取访问:安全吗?它快吗?_.net_Multithreading_Arrays_Multicore - Fatal编程技术网

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

.net int[]数组上的并发读取访问:安全吗?它快吗?,.net,multithreading,arrays,multicore,.net,Multithreading,Arrays,Multicore,在四核机器上,我正在考虑C#/.NET算法的并行化,这涉及到让多个线程同时读取小int[]数组。到目前为止,它似乎工作得相当好,但我不确定在哪里指定数组上的并发读取在.NET中是线程安全的。有什么建议吗 那么,我也想知道这种方法是否真的有效?在某些情况下,您是否最好实际复制每个线程的输入数据,这样就不会有任何并发读取,并且每个数组(可能?)都有机会缓存在CPU附近 关于多核CPU的最佳实践有什么想法吗?我认为并发读取没有问题。但是,如果存在并发写入操作,则可能会出现问题 不可变数据本质上是线程安

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

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


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

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


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

没有理由不同时读取数组的内容,前提是内容永远不会更改。没有并发问题,因此不需要复制


我怀疑你能做些什么来加快速度。

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

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

在您的情况下,通过阵列的并发读取将是线程安全的

至于算法的有效性,取决于阵列的大小,如果它适合缓存,那么您可能会看到出色的性能提升,因为多核在CPU中有效地“争夺”缓存。如果他们努力用相同的信息填充缓存,他们将共享更多的缓存命中率和更好的性能


假设您的数组适合缓存…

如果.NET性能和并行性受到威胁,我建议尝试用F#编写此特定算法。编译器将生成。

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

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

但是,如果存在写入新值的写入程序,则很容易受到竞争条件的影响

基本问题是,;读取器开始读取整数。该值从内存加载到寄存器中。在这一点上,读者交换了。然后写入程序更新内存中的值。然后,读取器将其交换回,并根据其加载的值进行操作——该值不再正确

这意味着像
if()
这样的东西不能可靠地工作。比如说,

if( int_array[5] == 10 )
{
}
int\u array[5]
的内存值不再为10时可能触发


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

不一定。在数组中,这不是问题,但在集合中,读取可能根本不是线程安全的。我完全同意您的观点,不可变数据是线程安全的。然而,有时很难确定数据是否不变。例如,对象上的明显读取操作(或者说“查询方法”)可能会导致内部写入。你必须时刻注意这一点。然而,对于数组:读取数组肯定不会改变它。@Steven同意,你不能总是判断某些东西是否是不变的。但我认为你的例子就是糟糕的设计。我相信不可变的数据(尤其是共享时)应该被明确地设计成这样。@Marthinho:你不知道我在我的载体中看到了多少糟糕的设计:-)它让我成为一个强迫性的、可疑的开发者。我不相信任何人,甚至我自己也不相信:-)然而,我同意你在这里所说的。@R.MartinhoFernandes一个显然是只读的方法执行写操作将是一个糟糕的设计?您可能有一个表示UTF-8字符串的类,该类具有允许检索代码点数量的getter。如果字符串经常被修改,您可能不希望每次都更新该代码点计数,而是将其标记为“dirty/to update”,并在有人试图使用getter检索其值时以静默方式更新它。这就是为什么C++有可变关键字,允许明显的“const”方法修改不代表对象公共状态的字段。