我在玩Go语言并发,发现有些东西对我来说是不透明的。我写了并行矩阵乘法,也就是说,每个任务计算乘积矩阵的单行,然后将源矩阵的相应行和列相乘。这是Java程序public static double[][] parallelMultiply(int nthreads, final double[][] m1, final double[][] m2) { final int n = m1.length, m = m1[0].length, l = m2[0].length; assert m1[0].length == m2.length; double[][] r = new double[n][]; ExecutorService e = Executors.newFixedThreadPool(nthreads); List<Future<double[]>> results = new LinkedList<Future<double[]>>(); for (int ii = 0; ii < n; ++ii) { final int i = ii; Future<double[]> result = e.submit(new Callable<double[]>() { public double[] call() throws Exception { double[] row = new double[l]; for (int j = 0; j < l; ++j) { for (int k = 0; k < m; ++k) { row[j] += m1[i][k]*m2[k][j]; } } return row; } }); results.add(result); } try { e.shutdown(); e.awaitTermination(1, TimeUnit.HOURS); int i = 0; for (Future<double[]> result : results) { r[i] = result.get(); ++i; } } catch (Exception ex) { ex.printStackTrace(); return null; } return r;}这是Go程序type Matrix struct { n, m int data [][]float64}func New(n, m int) *Matrix { data := make([][]float64, n) for i, _ := range data { data[i] = make([]float64, m) } return &Matrix{n, m, data}}func (m *Matrix) Get(i, j int) float64 { return m.data[i][j]}func (m *Matrix) Set(i, j int, v float64) { m.data[i][j] = v}func MultiplyParallel(m1, m2 *Matrix) *Matrix { r := New(m1.n, m2.m) c := make(chan interface{}, m1.n) for i := 0; i < m1.n; i++ { go func(i int) { innerLoop(r, m1, m2, i) c <- nil }(i) } for i := 0; i < m1.n; i++ { <-c } return r}
3 回答
慕容3067478
TA贡献1773条经验 获得超3个赞
您可能正在经历错误共享的影响。简而言之,如果两个数据恰好落在同一CPU高速缓存行上,则从在不同CPU内核上执行的线程修改这两个数据将触发昂贵的高速缓存一致性协议。
这种缓存“乒乓”非常难以诊断,并且可能在逻辑上完全不相关的数据上发生,只是因为它们恰好位于内存中足够近的位置。100%的CPU负载是虚假共享的典型代表-内核确实在100%工作,它们只是在您的程序上不工作-他们正在同步缓存。
在Java程序中,直到有时间将其“集成”到最终结果中之前,您都拥有线程专用数据,这使您免于错误共享。我不熟悉Go,但是从您自己的判断来看,线程直接将数据写入通用数组,这恰恰是可能触发错误共享的一种方式。这是一个示例,在多线程环境中,完全有效的单线程推理如何恰好相反!
要对该主题进行更深入的讨论,我热烈推荐Herb Sutter的文章:消除虚假共享,或进行一次演讲:机器体系结构:您的编程语言从不告诉您的事情(以及相关的PDF幻灯片)。
吃鸡游戏
TA贡献1829条经验 获得超7个赞
对于Linux,Windows 32和ditto 64,还有AMD的CodeXL和CodeAnalyst。由于适用的性能寄存器不同,他们将比在Intel上运行的应用程序更详细地描述在AMD处理器上运行的应用程序。
- 3 回答
- 0 关注
- 231 浏览
添加回答
举报
0/150
提交
取消