Go的口号是“不要通过共享内存来通信;相反,要通过通信来共享内存”。我想知道Go使用的是共享内存还是分布式计算方法。例如,对于MPI,它显然是分布式的,OpenMP显然是共享内存;但我不确定Go,这是唯一的。
我看过很多帖子,比如Shared memory vs. Go channel communication、effective Go document等,但都不清楚。提前谢谢。
发布于 2012-12-16 06:30:57
Go不会阻止你在goroutines/线程之间共享内存。他们所说的通信,是指您通过通道发送数据块或指向所述块的指针。这有效地将数据的“所有权”转移到通道的目标读取器。请注意,这种所有权转移不是由语言或运行时强制执行的,而只是约定。
如果您愿意的话,您仍然完全能够从两个goroutine写入相同的内存。换句话说: Go并没有阻止你搬起石头砸自己的脚,它只是提供了语言语义,使得这些错误更容易被发现。
如果将值传递到通道中,则程序员必须假定该值不再是他在同一goroutine中写入的值。
func F(c chan *T) {
// Create/load some data.
data := getSomeData()
// Send data into the channel.
c <- data
// 'data' should now be considered out-of-bounds for the remainder of
// this function. This is purely by convention, and is not enforced
// anywhere. For example, the following is still valid Go code, but will
// lead to problems.
data.Field = 123
}发布于 2012-12-16 21:52:29
这个问题假设共享内存和分布式计算是对立的。这有点像是在问: RAM和LAN是对立的吗?更清楚地区分CPU/内存节点内的共享内存并发性和CPU/内存节点之间的共享内存并发性。
这是并行处理研究的更大图景的一部分。已经有许多研究项目,包括:
第一个案例是专门针对高性能计算的。这是我们大多数人都熟悉的后一种情况。在这种情况下,如今的通信通常只是通过以太网,但已经(成功)为某些特定的利基市场开发了各种更快、更低延迟的替代方案(例如,从Transputer串行链路中出现的IEEE1355 SpaceWire )。
多年来,占主导地位的观点是,只有在共享内存的情况下才能实现有效的并行,因为通过传递消息进行通信的成本(天真地)被认为是令人望而却步的。对于共享内存并发,困难在于软件:因为一切都是相互依赖的,随着系统变得越来越大,设计并发变得越来越难。需要核心的专业知识。
对于我们其他人来说,Go遵循Erlang,Limbo,当然还有Occam,促进消息的传递作为编排要完成的工作的手段。这源于Communicating Sequential Processes的代数,它为创建任何规模的并行系统提供了基础。CSP设计是可组合的:每个子系统本身都可以是一个更大系统的组件,没有理论上的限制。
你的问题提到了OpenMP (共享内存)和MPI (分布式内存消息传递),它们可以一起使用。Go可以被认为大致等同于MPI,因为它促进了消息传递。然而,它也允许锁和共享内存。Go既不同于MPI,也不同于OpenMP,因为它不明确地与多处理器系统相关。要进入使用Go的并行处理的世界,就需要一个网络消息传递框架,比如OpenCL,有人正在为它开发Go API。
https://stackoverflow.com/questions/13895147
复制相似问题