【问题标题】:Shared read resources across threads跨线程共享读取资源
【发布时间】:2018-09-18 02:01:51
【问题描述】:

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

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

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

这些实体可能都是run() 在单个线程上按顺序排列,或者如果运行此代码的平台有利于这些实体可能会被批处理到多个 pthread 中,或者每个 run() 在它们自己的 pthread 上。

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

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

不考虑复制的成本,为我创建的每个线程复制simulation data 对我来说是个好主意,还是 CPU 可以在多个线程读取此资源时正常工作?如果simulation data 在堆栈中,这将如何改变。

【问题讨论】:

  • 你介绍了模拟数据,但没有描述它是什么或它的属性

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2015-01-13
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多