跨线程共享读取资源

时间:2018-09-18 02:01:52

标签: c++ linux multithreading operating-system cpu

这是一个有关多线程代码中读取性能的问题。

这就是这种情况。我有成千上万个实体需要知道的大量数据才能做出反应。此数据会更改每个帧,因此我们将其称为frame data

这些实体中的每一个都有一个需要运行的函数,每一帧都称为run()。函数run()需要经常读取(但不要写入)frame data。我们还假设frame data在堆中,因此在创建新线程时不会被克隆。

这些实体可以在单个线程上依次全部run(),或者如果运行此代码的平台受益,则可以将这些实体批处理成多个pthread或将每个run()放在它们自己的pthread中。 >

因此,基本上每个帧frame data都会更新,然后每个实体都会在任意线程上以任意顺序获取run()

我知道读取将花费相同的时间,但是我担心的是线程在等待另一个线程完成读取simulation data时被阻塞。这真的是一个有效的问题吗?

不考虑复制成本,对我创建的每个线程来说,制作一个simulation data的副本对我来说是一个好主意吗?或者,如果有多个线程读取该资源,那么CPU是否会正常?如果simulation data在堆栈中,将如何改变?

1 个答案:

答案 0 :(得分:0)

您似乎有一个经典的单作者/多读者队列。同步策略包括RW-lockCircular Ring Buffers

由于缓存,拥有单个副本绝对是最佳策略。在现代架构中,队列条目将被读取到高速缓存中,例如L3由第一个线程执行。同一CPU上的后续线程将避免从RAM重新读取内存。多个CPU的缓存中可能存在队列条目的多个副本。

线程将在CPU上进行时间分片,以便一次仅运行一个线程。在读取相同数据时,线程不会像互斥锁那样在串行锁定的意义上互相阻塞。

为每个线程创建多个副本将是一个坏主意。即使数据完全相同,副本也会使缓存过时。

堆栈不跨线程共享。如果队列元素在线程的本地堆栈上,则它是私有副本。如果通过指向主线程堆栈的指针访问队列元素,则将仅显示一个副本。一个线程访问另一个线程的堆栈通常是一个很糟糕的主意,但是很可能race conditions