-1

我已经编写了这个函数,我正在尝试使用Parallel.For或其他方式加速它。但是,当我用 a 替换其中一个循环时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
4

1 回答 1

1

您的实现绝对不是线程安全的。Parallel.For(和大多数方法)的要求之一Parallel是每个步骤必须是独立的。

来自MSDN

将顺序循环更改为并行循环很容易。然而,当你不应该使用并行循环时也很容易。这是因为很难判断这些步骤是否真的相互独立。学习如何识别一个步骤何时依赖于另一步骤需要练习。有时,在具有相关步骤的循环上使用此模式会导致程序以完全意想不到的方式运行,并且可能停止响应。其他时候,它引入了一个微妙的错误,在一百万次运行中只出现一次。换句话说,“独立”一词是该模式定义的关键部分,本章将详细解释。

您有 2 个外部变量YS,它们都在循环内被读取和写入。的每个线程都For在未知且不可预测的时间访问这些变量。有时甚至可能有 2 个线程同时从不同的内核同时访问这些变量。您无法知道循环的每次迭代中的状态S和所处的状态。Y

我对矩阵数学知之甚少,不知道是否有另一种实现你正在尝试做的事情可以使线程安全,但你拥有的那个肯定行不通。

于 2017-09-20T14:10:12.263 回答