在性能关键的代码中,我应该使用互斥锁(mutex)而不是通道(channel)吗?

huangapple go评论80阅读模式
英文:

Should I use mutexes instead of channels for performance-critical code?

问题

我正在阅读《Go并发编程》这本书,这个决策树是为了教我们选择使用“原语”还是“通道”。

这是一个性能关键的部分吗?

这绝对不意味着,“我希望我的程序具有高性能,因此我只会使用互斥锁。”相反,如果你的程序中有一个部分经过了性能分析,结果显示它是一个比程序其他部分慢几个数量级的主要瓶颈,那么使用内存访问同步原语可能有助于在负载下提高这个关键部分的性能。这是因为通道使用内存访问同步来操作,因此它们可能会更慢。然而,在我们考虑这一点之前,性能关键的部分可能暗示我们需要重构我们的程序。

但是它仍然没有解释为什么我们应该使用“通道”,因为性能总是很重要的,所以“我希望我的程序具有高性能,因此我只会使用互斥锁。”

所以我仍然不知道如何选择使用互斥锁还是通道。

英文:

在性能关键的代码中,我应该使用互斥锁(mutex)而不是通道(channel)吗?

I'm reading the book "Concurrency in Go" now and this decision tree is designed for teaching us to choose "primitives" or "channels".

> Is it a performance-critical section?

> This absolutely does not mean, “I want my program to be performant, therefore I will only use mutexes.” Rather, if you have a section of your program that you have profiled, and it turns out to be a major bottleneck that is orders of magni‐ tude slower than the rest of the program, using memory access synchronization primitives may help this critical section perform under load. This is because channels use memory access synchronization to operate, therefore they can only be slower. Before we even consider this, however, a performance-critical section might be hinting that we need to restructure our program.

But it still not explain why we should use channels, because performance always matters so “I want my program to be performant, therefore I will only use mutexes.”

So I still do not know how to choose using mutexes or channels.

答案1

得分: 4

根据性能选择通道和互斥锁的前提下,这种做法本质上是错误的。

通道更昂贵,因为它们具有更多的功能。通过从通道转换为原语,您会失去一些功能。

如果您的程序仍然正常工作,这意味着您一开始并不需要那些额外的功能。

如果您的程序不再工作,这意味着您需要“重新构建”以恢复丢失的功能。

通道在概念上非常简单,并且已经内置于语言和运行时本身(包括各种优化和技巧,这些技巧在用户代码中无法访问)。这意味着,实际上,任何试图从原语“重新构建”通道的尝试都会导致比chan更糟糕的实现。

英文:

The premise here of choosing between channel and mutex based on performance is bad at its core.

Channels are more expensive because they do more. By going from channels to primitives, you are losing some functionality.

If your program still works correctly, that means you didn't need that additional functionality to begin with.

If your program doesn't work anymore, that means you need to "build back up" to the lost functionality.

Channels are very simple in concept and are built into the language and runtime itself (including various optimizations and tricks you don't have access to in user-land code). This means that, practically speaking, any attempt to "build back up" from primitives will result in a worse implementation than chan.

huangapple
  • 本文由 发表于 2021年12月18日 18:27:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/70402617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定