这个问题探讨了向现有 Go 程序引入并发时意外的性能下降。该代码模拟游戏中与怪物的交互,跟踪成功的物品掉落。为了提高效率,程序员尝试使用并发在可用处理器之间分配工作负载,但这导致速度显着下降。
没有并发,程序会运行一系列模拟(本例中为 1000),并且每次模拟运行指定数量的交互(本例中为 1,000,000)。然后将结果用于计算成功交互的总数。
为了并行化代码,程序员创建多个 goroutine,每个 goroutine 负责运行一部分模拟。它们正确地将工作负载分配给可用的 CPU,将 goroutine 的数量与处理器的数量相匹配。
令人惊讶的是,并发代码不但没有提高性能,反而运行了 4-6 次比顺序对应的慢。
问题在于共享状态由并发 goroutine 访问。具体来说,rand.Float64() 函数使用具有关联互斥锁的共享全局 Rand 实例。当多个 goroutine 尝试访问全局 Rand 实例时,它们必须获取互斥锁,从而导致争用并减慢代码速度。
为了解决性能问题,程序员创建了一个每个 goroutine 都有单独的 Rand 实例。这消除了对全局 Rand 实例的争用,允许 goroutine 独立运行。
为每个 goroutine 创建单独的 Rand 实例可显着提高性能。现在,并发代码在双核 CPU 上的运行速度比非并发版本快约 2.5 倍。
此场景演示了了解共享资源使用的同步机制的重要性实现并发时。它强调了数据访问模式对性能的影响以及考虑处理器利用率和同步开销之间权衡的需要。
以上是为什么我的并发 Go 代码比其对应的串行代码慢?的详细内容。更多信息请关注PHP中文网其他相关文章!