title: No speedup in multithread program
body: <p>I was playing with Go language concurrency and found something which is kinda opaque to me.</p>
  
  <p>I wrote parallel matrix multiplication, that is, each task computes single line of product matrix, multiplying corresponding rows and columns of source matrices.</p>
  
  <p>Here is Java program</p>
  
  <pre><code>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&lt;Future&lt;double[]&gt;&gt; results = new LinkedList&lt;Future&lt;double[]&gt;&gt;();
      for (int ii = 0; ii &lt; n; ++ii) {
          final int i = ii;
          Future&lt;double[]&gt; result = e.submit(new Callable&lt;double[]&gt;() {
              public double[] call() throws Exception {
                  double[] row = new double[l];
                  for (int j = 0; j &lt; l; ++j) {
                      for (int k = 0; k &lt; 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&lt;double[]&gt; result : results) {
              r[i] = result.get();
              ++i;
          }
      } catch (Exception ex) {
          ex.printStackTrace();
          return null;
      }
  
      return r;
  }
  </code></pre>
  
  <p>and this is Go program</p>
  
  <pre><code>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 &amp;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 &lt; m1.n; i++ {
          go func(i int) {
              innerLoop(r, m1, m2, i)
              c &lt;- nil
          }(i)
      }
  
      for i := 0; i &lt; m1.n; i++ {
          &lt;-c
      }
  
      return r
  }
  
  func innerLoop(r, m1, m2 *Matrix, i int) {
      for j := 0; j &lt; m2.m; j++ {
          s := 0.0
          for k := 0; k &lt; m1.m; k++ {
              s = s + m1.Get(i, k) * m2.Get(k, j)
          }
          r.Set(i, j, s)
      }
  }
  </code></pre>
  
  <p>When I use Java program with nthreads=1 and nthreads=2 there is nearly double speedup on my dual-core N450 Atom netbook.
  When I use Go program with GOMAXPROCS=1 and GOMAXPROCS=2 there is no speedup at all!</p>
  
  <p>Even though Java code uses additional storage for <code>Future</code>s and then collectes their values to the result matrix instead of direct array update in the worker code (that's what Go version does), it performs <em>much</em> more faster on several cores than Go version.</p>
  
  <p>Especially funny is that Go version with GOMAXPROCS=2 loads both cores (htop displays 100% load on both processors while program works), but the time of computation is the same as with GOMAXPROCS=1 (htop displays 100% load only on one core in this case).</p>
  
  <p>Another concern is that Java program is faster than Go one even in simple single-thread multiplication, but that is not exactly unexpected (taking benchmarks from <a href="http://benchmarksgame.alioth.debian.org/" rel="nofollow noreferrer">here</a> into account) and should not affect multicore performance multiplier.</p>
  
  <p>What I'm doing incorrectly here? Is there a way to speedup Go program?</p>
  
  <p>UPD:
  it seems i found what I'm doing incorrectly. I was checking time of java program using <code>System.currentTimeMillis()</code> and Go program using <code>time</code> shell command. I mistakingly took 'user' time from zsh output as program working time instead of 'total' one. Now i double-checked the computation speed and it gives me nearly double speedup too (though it is slighlty lesser than Java's):</p>
  
  <pre><code>% time env GOMAXPROCS=2 ./4-2-go -n 500 -q
  env GOMAXPROCS=2 ./4-2-go -n 500 -q  22,34s user 0,04s system 99% cpu 22,483 total
  % time env GOMAXPROCS=2 ./4-2-go -n 500 -q -p
  env GOMAXPROCS=2 ./4-2-go -n 500 -q -p  24,09s user 0,10s system 184% cpu 13,080 total
  </code></pre>
  
  <p>Seems I have to be more attentive.</p>
  
  <p>Still java program gives five time lesser times on the same case. But it is a matter for another question I think.</p>