一行代码,为何使 24 核服务器比笔记本还慢(4)
时间:2023-06-27 01:44 来源:网络整理 作者:墨客科技 点击:次
为了能够使用独立的 Unit 和 RuntimeContext,我提交了一个 补丁 给 Rune,使它们可 Clone。然后,在 Latte 这边,整个修复实际上是引入了一个新的函数用于 " 深度 " 克隆 Program 结构,然后确保每个线程都获取它自己的副本: // Makes a deep copy of context and unit. // Calling this method instead of `clone` ensures that Rune runtime structures // are separate and can be moved to different CPU cores efficiently without accidental // sharing of Arc references. fn unshare ( &self ) -> Program { Program { sources: self.sources.clone ( ) , context: Arc::new ( self.context.as_ref ( ) .clone ( ) ) , // clones the value under Arc and wraps it in a new counter unit: Arc::new ( self.unit.as_ref ( ) .clone ( ) ) , // clones the value under Arc and wraps it in a new counter } } 顺便说一下:sources 字段在执行过程中除了用于发出诊断信息并未被使用,所以它可以保持共享。 注意,我最初发现性能下降的那一行代码并不需要任何改动! Vm::new ( self.context.clone ( ) , self.unit.clone ( ) ) 这是因为 self.context 和 self.unit 不再在线程之间共享。幸运的是频繁更新非共享计数器通常很快。 最终结果 现在吞吐量按符合预期,从 1 到 24 个线程吞吐量线性增大 : 经验总结 在某些硬件配置上,如果在多个线程上频繁更新一个共享的 Arc,其代价可能会高得离谱。 不要假设单条汇编指令不可能造成性能问题。 不要假设在单个 CPU 上表现良好的应用程序也会在多 CPU 机器上具有相同的性能表现和可扩展性。 (责任编辑:admin) |
