int count = trees.Count; var sim = new TriangularMatrix(count); var partitioner = Partitioner.Create(0, sim.Length); var locker = new object(); var calculated = 0; Parallel.ForEach(partitioner, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (range, loop) => { var calc = new SymbolicExpressionTreeBottomUpSimilarityCalculator(); int startRow, endRow, startCol, endCol; sim.GetMatrixCoordinates(range.Item1, out startRow, out startCol); sim.GetMatrixCoordinates(range.Item2 - 1, out endRow, out endCol); for (int i = startRow; i <= endRow; ++i) { var start = i == startRow ? startCol : 0; var end = i == endRow ? endCol : i; for (int j = start; j <= end; ++j) { var s = i == j ? 1 : calc.CalculateSimilarity(trees[i], trees[j]); sim[i, j] = 1 - s; } } lock (locker) { calculated += range.Item2 - range.Item1; Console.WriteLine("{0} / {1} calculated", calculated, sim.Length); } });