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

发布于 2024-07-13 22:39:03 字数 252 浏览 7 评论 0原文

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

那么我也想知道这种做法真的有效吗? 在某些情况下,您最好实际上为每个线程复制输入数据,这样就不会出现任何并发读取,并且每个数组(也许?)都有机会在亲和性 CPU 附近缓存?

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

On a quad-core machine, I am considering the parallelization of C#/.NET algorithm which involves having multiple threads reading the small int[] array concurrently. So far, it seems to be working rather well, but I am not sure where it is specified that concurrent reads on an array are thread-safe in .NET. Any pointers?

Then, I am also wondering if this approach is really efficient? Are there situations where you are better off actually duplicating the input data for each thread, so that there isn't any concurrent read, and each array (maybe?) gets the opportunity to be cached near affinity CPU?

Any thoughts on the best practices in respect of multicore CPUs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浮云落日 2024-07-20 22:39:03

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

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

I don't think there's a problem with concurrent reads. It could be problematic if there are concurrent writes, though.

Immutable data is inherently thread-safe.

删除会话 2024-07-20 22:39:03

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

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

假设您的数组适合缓存......

In your case, concurrent reads over your array will be thread safe.

As for your algorithms effectiveness, depending on the size of your array, if it will fit in the cache then you may see excellent performance gains, as the multicores effectively "fight" for cache in the CPU. If they are fighting to fill the cache with the same information, they will share meaning more cache hits and better performance.

Assuming that your array fits into the cache...

冷情妓 2024-07-20 22:39:03

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

我怀疑您是否可以做很多事情来使其更快。

There is no reason not read the content of an array concurrently assuming that is content will never change. There is no concurrency issue hence no need to copy.

I doubt there is much you can do to make it faster either.

仙女山的月亮 2024-07-20 22:39:03

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

It shouldn't bother you. Concurrent read is not a problem. Any number of threads can read the same memory at the same time.

一个人练习一个人 2024-07-20 22:39:03

如果 .NET 性能和并行性受到威胁,我建议尝试在 F# 中编写此特定算法。 F# 编译器将生成 .NET 代码具有 2-6 更好的性能

If .NET performance and parallelism are at stake, I'd recommend to try writing this specific algorithm in F#. F# compiler will generate .NET code that has 2-6 better performance.

叹梦 2024-07-20 22:39:03

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

Thread-safety is only an issue when you update data. If you have multiple concurrent threads updating the array you will have to wrap the updates (and reads if the updates are not atomic) in a synchronisation mechanism. For a read-only data structure the concurrency is a non-issue.

苏辞 2024-07-20 22:39:03

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

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

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

基本问题是这样的; 读者开始读取一个整数。 该值从内存加载到寄存器中。 此时,读者换出。 然后写入器更新内存中的值。 然后,读取器换回并根据他加载的值进行操作 - 这不再正确。

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

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

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

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

The assignment operator is not thread safe.

This means if your threads are only reading the array - if the array was initialized at programme start and does not change - then you are safe.

However, if a writer exists who writes new values, you are vulnerable to a race condition.

The basic issue is this; a reader begins to read an integer. The value is loaded from memory into a register. At this point, the reader swaps out. The writer then updates the value in memory. The reader then swaps back in and acts on the value he loaded - which is no longer correct.

This means that things like if() do not work reliably. For example,

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

May trigger when the in-memory value of int_array[5] is no longer 10.

I believe in C#, you should have access to the Interlocked*() function calls, such as InterlockedCompareAndSwap(). These will permit you to easily achieve thread safety in this case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文