Parallel processing goroutine是否适用于大型并行计算范围的问题?
对于数值问题,go例程是否预先多任务处理 我对Go的精益设计、速度非常感兴趣,但最感兴趣的是通道是一流的对象。我希望最后一点可以通过复杂的互连模式,为大数据提供一种全新的深度分析算法 我的问题域需要对流式传入数据进行实时计算范围分析。数据可以划分为100-1000个“问题”,每个问题需要10到1000秒的时间来计算(即,它们的粒度是高度可变的)。然而,在输出有意义之前,结果必须全部可用,即,假设500个问题出现,并且在我可以使用其中任何一个之前,所有500个问题都必须得到解决。该应用程序必须能够扩展到数千个(但不太可能是上千个)问题 考虑到我不太担心数字库支持(这些东西大部分都是定制的),Go看起来很理想,因为我可以将每个问题映射到goroutine。在我投资学习Go而不是说,Julia、Rust或函数式语言(据我所知,这些语言都没有一流的渠道,因此对我来说都处于直接劣势)之前,我需要知道goroutines是否正确地先发制人地执行多任务。也就是说,如果我在一台功能强大的多核计算机上运行500个绑定到计算的goroutines,我可以期望在所有“问题”之间实现合理的负载平衡,还是必须始终以1995年的方式合作“屈服”。考虑到问题的粒度是可变的,而且在计算过程中,我通常不知道需要多长时间,所以这个问题尤其重要Parallel processing goroutine是否适用于大型并行计算范围的问题?,parallel-processing,go,goroutine,Parallel Processing,Go,Goroutine,对于数值问题,go例程是否预先多任务处理 我对Go的精益设计、速度非常感兴趣,但最感兴趣的是通道是一流的对象。我希望最后一点可以通过复杂的互连模式,为大数据提供一种全新的深度分析算法 我的问题域需要对流式传入数据进行实时计算范围分析。数据可以划分为100-1000个“问题”,每个问题需要10到1000秒的时间来计算(即,它们的粒度是高度可变的)。然而,在输出有意义之前,结果必须全部可用,即,假设500个问题出现,并且在我可以使用其中任何一个之前,所有500个问题都必须得到解决。该应用程序必须能够
如果另一种语言能更好地为我服务,我很高兴听到这个消息,但我有一个要求,即执行的线程(或go/coroutines)是轻量级的。例如,Python多处理模块对于我的扩展野心来说,资源过于密集。先说一句:我确实理解并行性和并发性之间的区别 我不确定我是否完全理解您,但是您可以设置为缩放到所有进程,然后使用通道(或锁)同步数据,例如:
const N = 100
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) //scale to all processors
var stuff [N]bool
var wg sync.WaitGroup
ch := make(chan int, runtime.NumCPU())
done := make(chan struct{}, runtime.NumCPU())
go func() {
for i := range ch {
stuff[i] = true
}
}()
wg.Add(N)
for i := range stuff {
go func(i int) {
for { //cpu bound loop
select {
case <-done:
fmt.Println(i, "is done")
ch <- i
wg.Done()
return
default:
}
}
}(i)
}
go func() {
for _ = range stuff {
time.Sleep(time.Microsecond)
done <- struct{}{}
}
close(done)
}()
wg.Wait()
close(ch)
for i, v := range stuff { //false-postive datarace
if !v {
panic(fmt.Sprintf("%d != true", i))
}
}
fmt.Println("All done")
}
const N=100
func main(){
runtime.GOMAXPROCS(runtime.numpu())//扩展到所有处理器
var stuff[N]bool
var wg sync.WaitGroup
ch:=make(chan int,runtime.numpu())
完成:=make(chan struct{},runtime.numpu())
go func(){
对于i:=范围ch{
真的
}
}()
工作组.添加(N)
对于i:=范围对象{
go func(i int){
对于{//cpu绑定循环
挑选{
caseGo运行时有一个模型,其中多个Go例程以自动方式映射到多个线程。没有Go例程绑定到某个线程,调度程序可能(也将)将Go例程安排到下一个可用线程。Go程序使用的线程数取自GOMAXPROCS
环境变量,可以用()覆盖。这是一个简化的描述,足以理解
在以下情况下,Go例程可能会产生:
- 在任何可能阻塞的操作上,即任何无法当场返回结果的操作,因为它是(可能的)阻塞系统调用,如
io.Read()
,或可能需要等待其他Go例程的操作,如获取互斥锁或向通道发送或从通道接收
- 关于各种运行时操作
- 如果调度程序检测到抢占的Go例程占用了大量CPU时间,则调用函数(这在Go 1.2中是新的)
- 随叫随到
- 论恐慌
- 从Go 1.14开始,紧循环可以被运行时抢占。因此,没有函数调用的循环不再可能使调度程序死锁或显著延迟垃圾收集。这在所有平台上都不受支持-请务必这样做。另请参阅此区域中有关未来计划的问题
- 在其他各种场合
以下几点会阻止围棋程序屈服:
- 执行C代码。当Go例程通过cgo执行C代码时,它不能屈服
- 调用(),直到调用()为止
据我所知,Go确实做到了这一点。如果所有Go例程都是非阻塞的,Go将基于时间片在它们之间进行切换。并且重数值计算是“非阻塞”的吗?什么会阻止goroutine?@Thomad Browne:阻止函数是那些需要暂停您的Go例程直到结果可用的函数,例如发送到频道/从频道接收、调用runtime.Gosched()或执行IO。如果您的函数不执行这些操作,则它不是阻止函数。旁白:截至今天(2017年底),Julia确实有频道支持。我想他想知道Go调度程序是否是抢占式的。这看起来很有趣,但我对Go的了解还不够,无法完全理解代码中所做的事情。我已经成功编译并执行了它,似乎我得到了类似于序列的行为。我以为我会得到mo100个结果中的st“聚束”在输出过程中?我想做的是修改您的代码,使每个goroutine中的工作负载大致相等,然后我可以看到不同N.在我的理解中,您正在启动100个go例程,当它们完成时,他们会告诉我,但是您给每个goroutine做了多少工作?全部100 should理论上是在同一时间运行的,当一个人完成时,它会将结果推送到通道,它看起来是串行的原因是,在向随机goroutine发送信号之前,我只睡了1微秒,然后它就完成了(注意这里的完成了两个非常有趣的项目:“如果[it]占用了大量CPU时间,则调用函数”。这是我对每个Go例程的使用案例。也就是“执行不包含函数调用的紧密循环”。所以基本上