C# 为什么LU分解使用并行。对于不工作?

C# 为什么LU分解使用并行。对于不工作?,c#,parallel-processing,linear-algebra,parallel.foreach,matrix-decomposition,C#,Parallel Processing,Linear Algebra,Parallel.foreach,Matrix Decomposition,我正试图用杜立特算法解决LU分解问题——根据这一点。没有并行化,代码就可以正常工作。然而,我想让这段代码并行运行——尝试创建一个并行的外部循环和两个内部循环。不幸的是,我仍然缺少一些东西。如果我试图首先使外部循环并行运行,我会收到一个糟糕的结果 我试着找出可能发生碰撞的地方。后来我锁上了那些地方,但仍然没有收到正确的结果。我将它们作为注释添加到复制的代码中。我做错了什么,我需要把其他地方锁起来吗? 外环的正确实现是什么? 内部循环会是什么样子? 先谢谢你 算法的实现(顺序) 平行不良结果 编

我正试图用杜立特算法解决LU分解问题——根据这一点。没有并行化,代码就可以正常工作。然而,我想让这段代码并行运行——尝试创建一个并行的外部循环和两个内部循环。不幸的是,我仍然缺少一些东西。如果我试图首先使外部循环并行运行,我会收到一个糟糕的结果

我试着找出可能发生碰撞的地方。后来我锁上了那些地方,但仍然没有收到正确的结果。我将它们作为注释添加到复制的代码中。我做错了什么,我需要把其他地方锁起来吗? 外环的正确实现是什么? 内部循环会是什么样子? 先谢谢你



算法的实现(顺序)

平行不良结果

编辑 我试着用一把锁锁上所有通往田地的道路。我知道这样会失去所有的并行化。然而,我希望至少取得正确的结果,不幸的是没有成功

 static object mylock = new object();
            //making outer loop parallel
            Parallel.For(0, n, (i, state) =>
            {
                for (int j = i; j < n; j++)
                {
                    for (int k = 0; k < i; k++)
                    {
                        lock (mylock)
                        {
                            upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
                        }
                    }
                }

                for (int j = i + 1; j < n; j++)
                {
                    for (int k = 0; k < i; k++)
                    {
                        lock (mylock)
                        {
                            lower[j, i] = lower[j, i] - (lower[j, k] * upper[k, i]);
                        }
                    }
                    lock (mylock)
                    {
                        lower[j, i] = lower[j, i] / upper[i, i];
                    }
                }
            });
static object mylock=new object();
//使外环平行
对于(0,n,(i,状态)=>
{
对于(int j=i;j
并行循环写入同一数组,对吗

upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
但它没有定义,哪个循环将写入数组中的某个位置时。因此,两个循环不会写入同一个索引,而是从另一个循环可能已经写入的索引中读取。
你不能这样并行化你的算法

引人注目的一件事是,您修改了
上部
下部
数组,并在不进行任何同步的情况下从多个线程中读取它们(如
锁定
)。我先在
lock
中包围所有上下通道,看看这是否修复了坏结果。当然,这不是一个解决方案,因为它会破坏并行化效果,但只是为了确认问题。最好将结果作为文本而不是图像包含。
如果没有并行化,代码可以正常工作。
请向我们展示您的“非并行”代码。如果我错了,请纠正我,但
upper[I,j]=上[i,j]-(下[i,k]*上[k,j])看起来每个循环都依赖于前面的步骤。也就是说,当
I=2
计算
upper[2,2]
时,使用
upper[1,2]
,这是在
I=1
@Evk循环中计算的,即使我用一个锁锁定了所有访问,我也会得到一个坏结果。好的,我明白你的意思。甚至有可能使这个算法以某种方式并行运行吗?我将尝试寻找其他可能的解决方案。n的最大值通常是多少?顺便说一句。您是舒尔吗,您的(int k=0;kConcatenation Upper triangle Lower triangle 2 -1 -2 2 -1 -2 1 0 0 -2 4 -1 0 4 -1 -2 1 0 -2 -1 3 0 0 3 -2 -1 1
Concatenation  Upper triangle    Lower triangle
 2 -1 -2       2 -1 -2             1  0  0
-2  4 -1       0  4 -1            -2  1  0
-2 -1  3       0  0 10 -->BAD     -2 -1  1
 static object mylock = new object();
            //making outer loop parallel
            Parallel.For(0, n, (i, state) =>
            {
                for (int j = i; j < n; j++)
                {
                    for (int k = 0; k < i; k++)
                    {
                        lock (mylock)
                        {
                            upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);
                        }
                    }
                }

                for (int j = i + 1; j < n; j++)
                {
                    for (int k = 0; k < i; k++)
                    {
                        lock (mylock)
                        {
                            lower[j, i] = lower[j, i] - (lower[j, k] * upper[k, i]);
                        }
                    }
                    lock (mylock)
                    {
                        lower[j, i] = lower[j, i] / upper[i, i];
                    }
                }
            });
upper[i, j] = upper[i, j] - (lower[i, k] * upper[k, j]);