代码之家  ›  专栏  ›  技术社区  ›  J.Doe

跨线程共享读取资源

  •  2
  • J.Doe  · 技术社区  · 6 年前

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

    所以情况是这样的。我有大量的数据,几千个实体需要知道才能做出反应。这些数据会改变每一帧,所以我们可以调用它 frame data .

    每个实体都有一个需要运行的函数,每个帧都可以调用它 run() . 函数run()需要经常读取(但从不写入)到 帧数据 . 我们还假设 帧数据 在堆中,因此在创建新线程时不会克隆。

    这些实体可能都是 运行() 在单个线程上按顺序执行,或者如果运行此代码的平台对实体有利,则可以将实体批处理为多个pthread或每个pthread 运行() 在他们自己的pthread上。

    所以基本上每一帧 帧数据 更新,然后每个实体都得到 运行() 在任意线程上以任意顺序。

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

    不管复制的成本如何,我复制一份 仿真数据 对于我创建的每个线程,或者多个线程读取此资源时CPU是否正常?如果 仿真数据 在堆栈上。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Matthew Fisher    6 年前

    您似乎有一个经典的单写/多读队列。有几种同步策略包括 RW-lock Circular Ring Buffers

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

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

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

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