跨线程共享读取资源



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

所以情况是这样的。我有大量的数据,几千个实体需要知道这些数据才能做出反应。此数据会更改每一帧,因此我们将其称为frame data

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

这些实体可能全部按顺序在单个线程上run(),或者如果运行此代码的平台有利于这些实体,则可以将实体批处理到多个 pthread,或者每个run()在自己的 pthread 上。

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

我意识到无论如何读取都将花费相同的时间,但我担心的是线程在等待另一个线程完成读取simulation data时被阻塞。这是一个合理的担忧吗?

不考虑复制的成本,为我创建的每个线程复制simulation data是一个好主意,还是 CPU 可以接受多个线程读取此资源?如果simulation data在堆栈上,这将如何变化。

您似乎有一个经典的单写入器/多读取器队列。 有几种同步策略,包括 RW 锁定和圆形环形缓冲区

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

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

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

堆栈不会在线程之间共享。 如果队列元素位于线程的本地堆栈上,则它是私有副本。 如果队列元素是通过指向主线程堆栈的指针访问的,则只会存在一个副本。 让一个线程访问另一个线程的堆栈通常是一个糟糕的主意,但是因为可能会出现竞争条件。

最新更新