使用 Parallel.For 加速函数
Speeding up a function with Parallel.For
我已经编写了这个函数,我正在尝试使用 Parallel.For
或其他方式加快它的速度。但是,当我用 Parallel.For
替换其中一个循环时,它给出了错误的结果。
Public Function InverseFromUpperTriangular(U As Matrix) As Matrix
Dim n As Integer = U.RowCount
Dim Y As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Dim S As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
For j = n - 1 To 0 Step -1
S(j, j) = 1.0 / U(j, j)
For i = j To 0 Step -1
Y(i, j) = (S(i, j) - U.Row(i).SubVector(i, n - i) * Y.Column(j).SubVector(i, n - i)) / U(i, i)
Y(j, i) = Y(i, j)
Next
Next
Return Y
End Function
编辑
这是我的函数 Parallel.For
Public Function InverseFromUpperTriangular(U As Matrix) As Matrix
Dim n As Integer = U.RowCount
Dim Y As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Dim S As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Parallel.For(0, n, Sub(ii)
Dim j = n - 1 - ii
S(j, j) = 1.0 / U(j, j)
For i = j To 0 Step -1
Y(i, j) = (S(i, j) - U.Row(i).SubVector(i, n - i) * Y.Column(j).SubVector(i, n - i)) / U(i, i)
Y(j, i) = Y(i, j)
Next
End Sub)
Return Y
End Function
您的实现绝对不是线程安全的。 Parallel.For
(以及大多数 Parallel
方法)的要求之一是每个步骤必须独立。
来自MSDN:
It's easy to change a sequential loop into a parallel loop. However,
it's also easy to use a parallel loop when you shouldn't. This is
because it can be hard to tell if the steps are actually independent
of each other. It takes practice to learn how to recognize when one
step is dependent on another step. Sometimes, using this pattern on a
loop with dependent steps causes the program to behave in a completely
unexpected way, and perhaps to stop responding. Other times, it
introduces a subtle bug that only appears once in a million runs. In
other words, the word "independent" is a key part of the definition of
this pattern, and one that this chapter explains in detail.
您有 2 个外部变量,Y
和 S
,它们都在循环内读取和写入。 For
的每个线程都在未知且不可预测的时间访问这些变量。有时甚至可能有 2 个线程同时从不同内核同时访问这些变量。您无法知道 S
和 Y
在循环的每次迭代中所处的状态。
我对矩阵数学的了解还不够多,不知道是否有另一种实现你正在尝试做的事情 可以 线程安全,但你有肯定不行。
我已经编写了这个函数,我正在尝试使用 Parallel.For
或其他方式加快它的速度。但是,当我用 Parallel.For
替换其中一个循环时,它给出了错误的结果。
Public Function InverseFromUpperTriangular(U As Matrix) As Matrix
Dim n As Integer = U.RowCount
Dim Y As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Dim S As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
For j = n - 1 To 0 Step -1
S(j, j) = 1.0 / U(j, j)
For i = j To 0 Step -1
Y(i, j) = (S(i, j) - U.Row(i).SubVector(i, n - i) * Y.Column(j).SubVector(i, n - i)) / U(i, i)
Y(j, i) = Y(i, j)
Next
Next
Return Y
End Function
编辑
这是我的函数 Parallel.For
Public Function InverseFromUpperTriangular(U As Matrix) As Matrix
Dim n As Integer = U.RowCount
Dim Y As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Dim S As Matrix = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(n, n)
Parallel.For(0, n, Sub(ii)
Dim j = n - 1 - ii
S(j, j) = 1.0 / U(j, j)
For i = j To 0 Step -1
Y(i, j) = (S(i, j) - U.Row(i).SubVector(i, n - i) * Y.Column(j).SubVector(i, n - i)) / U(i, i)
Y(j, i) = Y(i, j)
Next
End Sub)
Return Y
End Function
您的实现绝对不是线程安全的。 Parallel.For
(以及大多数 Parallel
方法)的要求之一是每个步骤必须独立。
来自MSDN:
It's easy to change a sequential loop into a parallel loop. However, it's also easy to use a parallel loop when you shouldn't. This is because it can be hard to tell if the steps are actually independent of each other. It takes practice to learn how to recognize when one step is dependent on another step. Sometimes, using this pattern on a loop with dependent steps causes the program to behave in a completely unexpected way, and perhaps to stop responding. Other times, it introduces a subtle bug that only appears once in a million runs. In other words, the word "independent" is a key part of the definition of this pattern, and one that this chapter explains in detail.
您有 2 个外部变量,Y
和 S
,它们都在循环内读取和写入。 For
的每个线程都在未知且不可预测的时间访问这些变量。有时甚至可能有 2 个线程同时从不同内核同时访问这些变量。您无法知道 S
和 Y
在循环的每次迭代中所处的状态。
我对矩阵数学的了解还不够多,不知道是否有另一种实现你正在尝试做的事情 可以 线程安全,但你有肯定不行。