起因
最近在用go写一个raytracing光线追踪器,光线追踪针对每一个光线进行跟踪并计算最终结果,且每个光线之间互不干扰,非常适合利用并行计算进行计算时间的优化。
问题
然而当我将计算并行化之后却发现并行计算的时间居然远远超出单线程的计算时间,十分怪异。一开始认为是开启太多goroutine导致调度负载过高而拖慢计算,排查后发现显然不是。
遂利用go自带的pprof工具采集cpu信息进行分析,发现sync.(*Mutex).lockSlow消耗了大量的时间,在排除了本身程序架构上的锁问题之后,那么,是什么导致如此长时间的锁消耗呢?
解决
经过研究,最终发现问题出在使用的rand.Float64()函数上。math/rand包中的函数默认使用了一个全局锁,在并发加高频率调用的情况下,全局锁损耗非常大。
解决方法也比较简单,对每个并发的goroutine,单独生成一个rand就行了。
source := rand.NewSource(time.Now().UnixNano())
generator := rand.New(source)
有疑问加站长微信联系(非本文作者)