You made some small mistakes, for example, you did not understand how to perform matrix multiplication.
let myBigElemMultiply (m:matrix) (n:matrix) = let AddTwoRows (row:int) (destination:matrix) (source1:matrix) (source2:matrix) = for col=0 to destination.NumCols-1 do let mutable sum = 0.0 for k=0 to m.NumCols-1 do sum <- sum + source1.[row,k] * source2.[k,col] destination.[row,col] <- sum let result = Matrix.zero m.NumRows n.NumCols let operations = [ for i=0 to m.NumRows-1 do yield async { AddTwoRows i result mn} ] let parallelTasks = Async.Parallel operations Async.RunSynchronously parallelTasks |> ignore result
It should be noted that this code will work very poorly, because m.[i,j] is an inefficient way to access the elements in the matrix. You better use a 2D array:
let myBigElemMultiply2 (m:matrix) (n:matrix) = let AddTwoRows (row:int) (destination:matrix) (source1:matrix) (source2:matrix) = let destination = destination.InternalDenseValues let source1 = source1.InternalDenseValues let source2 = source2.InternalDenseValues for col=0 to Array2D.length2 destination - 1 do let mutable sum = 0.0 for k=0 to Array2D.length1 source2 - 1 do sum <- sum + source1.[row,k] * source2.[k,col] destination.[row,col] <- sum let result = Matrix.zero m.NumRows n.NumCols let operations = [ for i=0 to m.NumRows-1 do yield async { AddTwoRows i result mn} ] let parallelTasks = Async.Parallel operations Async.RunSynchronously parallelTasks |> ignore result
Testing:
let r = new Random() let A = Matrix.init 280 10340 (fun ij -> r.NextDouble() ) let B = A.Transpose
some time:
> myBigElemMultiply AB;; Real: 00:00:22.111, CPU: 00:00:41.777, GC gen0: 0, gen1: 0, gen2: 0 val it : unit = () > myBigElemMultiply2 AB;; Real: 00:00:08.736, CPU: 00:00:15.303, GC gen0: 0, gen1: 0, gen2: 0 val it : unit = () > A*B;; Real: 00:00:13.635, CPU: 00:00:13.166, GC gen0: 0, gen1: 0, gen2: 0 val it : unit = () >
Check here using ParallelFor, which should have better performance than asynchronous.