' How to: Write a Simple Parallel.For Loop
Imports System.Threading.Tasks
Imports System.Threading.Tasks.Parallel
Module MultiplyMatrices
#Region "Sequential_Loop"
Private Sub MultiplyMatricesSequential(ByVal matA As Double(,), ByVal matB As Double(,), ByRef resultS As Double(,))
Dim matACols As Integer = matA.GetLength(1)
Dim matBCols As Integer = matB.GetLength(1)
Dim matARows As Integer = matA.GetLength(0)
Dim temp As Double = 0
For i As Integer = 0 To matARows - 1
For j As Integer = 0 To matBCols - 1
temp = 0
For k As Integer = 0 To matACols - 1
temp += matA(i, k) * matB(k, j) / 3
Next
resultS(i, j) += temp
Next
Next
End Sub
#End Region
#Region "Parallel_Loop"
Private Function MultiplyMatricesParallel(ByVal matA As Double(,), ByVal matB As Double(,), ByVal resultP As Double(,))
Dim matACols As Integer = matA.GetLength(1)
Dim matBCols As Integer = matB.GetLength(1)
Dim matARows As Integer = matA.GetLength(0)
' A basic matrix multiplication.
' Parallelize the outer loop to partition the source array by rows.
Threading.Tasks.Parallel.For(0, matARows, Sub(i)
Dim temp As Double = 0
For j As Integer = 0 To matBCols - 1
' Use a temporary to improve parallel performance.
temp = 0
For k As Integer = 0 To matACols - 1
temp += matA(i, k) * matB(k, j) / 3
Next
resultP(i, j) += temp
Next
End Sub)
Return resultP
End Function
#End Region
#Region "Main"
Sub Main(ByVal args As String())
Inizia:
' Set up matrices. Use small values to better view
' result matrix. Increase the counts to see greater
' speedup in the parallel loop vs. the sequential loop.
Dim colCount As Integer = 500
Dim rowCount As Integer = 1500
Dim colCount2 As Integer = 700
Dim m1 As Double(,) = InitializeMatrix(rowCount, colCount)
Dim m2 As Double(,) = InitializeMatrix(colCount, colCount2)
Dim result_S As Double(,) = New Double(rowCount - 1, colCount2 - 1) {}
Dim result_P As Double(,) = New Double(rowCount - 1, colCount2 - 1) {}
' First do the sequential version.
Console.WriteLine("-S")
Console.WriteLine("Executing sequential loop...")
Dim stopwatch As New Stopwatch()
stopwatch.Start()
MultiplyMatricesSequential(m1, m2, result_S)
stopwatch.[Stop]()
Console.WriteLine("Sequential loop time in milliseconds: {0}", stopwatch.ElapsedMilliseconds)
' For the skeptics.
OfferToPrint(rowCount, colCount2, result_S)
' Reset timer and results matrix.
stopwatch.Reset()
result_S = Nothing
' Do the parallel loop.
Console.WriteLine("-P")
Console.WriteLine("Executing parallel loop...")
stopwatch.Start()
result_P = MultiplyMatricesParallel(m1, m2, result_P)
stopwatch.[Stop]()
Console.WriteLine("Parallel loop time in milliseconds: {0}", stopwatch.ElapsedMilliseconds)
OfferToPrint(rowCount, colCount2, result_P)
Console.WriteLine("Vuoi riprovare? y/n")
Dim c As Char = Console.ReadKey().KeyChar
If c = "y"c OrElse c = "Y"c Then
Console.WriteLine()
GoTo Inizia
End If
' Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
#End Region
#Region "Helper_Methods"
Function InitializeMatrix(ByVal rows As Integer, ByVal cols As Integer) As Double(,)
Dim matrix As Double(,) = New Double(rows - 1, cols - 1) {}
Dim r As New Random()
For i As Integer = 0 To rows - 1
For j As Integer = 0 To cols - 1
matrix(i, j) = r.[Next](100000)
Next
Next
Return matrix
End Function
Sub OfferToPrint(ByVal rowCount As Integer, ByVal colCount As Integer, ByRef matrix As Double(,))
Console.WriteLine("Computation complete. Print results? y/n")
Console.WriteLine()
Dim c As Char = Console.ReadKey().KeyChar
If c = "y"c OrElse c = "Y"c Then
'Console.WindowWidth = 168
Console.WriteLine()
For x As Integer = 0 To rowCount - 1
Console.WriteLine("ROW {0}: ", x)
For y As Integer = 0 To colCount - 1
Console.Write("{0:#.##} ", matrix(x, y))
Next
Console.WriteLine(" Continue ? y/n")
c = Console.ReadKey().KeyChar
If c = "n"c OrElse c = "N"c Then
Exit For
End If
Next
End If
End Sub
#End Region
End Module