C# 并行使用共享变量

C# 并行使用共享变量,c#,parallel.foreach,C#,Parallel.foreach,我正在努力使用Parallel.For,而不是For循环。 由于CoefficientVector数组的大小相当大,因此对我来说,只有重置数组元素值,而不是为每次迭代创建新值才有意义 我尝试用并行的For替换外环;假设并行for的每个分区由一个单独的线程运行,将有它自己的CoefficientVector类副本,因此对我来说,每个线程有一个CoefficientVector对象实例并重置向量元素而不是重新创建数组是有意义的。我觉得很难同时进行这种优化(?)。谁能帮忙吗 static void

我正在努力使用Parallel.For,而不是For循环。 由于CoefficientVector数组的大小相当大,因此对我来说,只有重置数组元素值,而不是为每次迭代创建新值才有意义

我尝试用并行的For替换外环;假设并行for的每个分区由一个单独的线程运行,将有它自己的CoefficientVector类副本,因此对我来说,每个线程有一个CoefficientVector对象实例并重置向量元素而不是重新创建数组是有意义的。我觉得很难同时进行这种优化(?)。谁能帮忙吗

 static void Main(string[] args)
    {
        System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
        timer.Start(); 

        int numIterations = 20000;
        int numCalpoints = 5000;
        int vecSize = 10000;

        CalcPoint[] calcpoints = new CalcPoint[numCalpoints];

        CoefficientVector coeff = new CoefficientVector();
        coeff.vectors = new Vector[vecSize];

        //not sure how to correctly use Parallel.For here
        //Parallel.For(0, numCalpoints, =>){
        for (int i = 0; i < numCalpoints;i++)
        {
            CalcPoint cp = calcpoints[i];

            //coeff.vectors = new Vector[vecSize];
            coeff.ResetVectors();

            //doing some operation on the matrix n times
            for (int n = 0; n < numIterations; n++)
            {
                coeff.vectors[n].x += n;
                coeff.vectors[n].y += n;
                coeff.vectors[n].z += n;
            }

            cp.result = coeff.GetResults();
        }

        Console.Write(timer.Elapsed);
        Console.Read();
    }
}

class CoefficientVector
{
    public Vector[] vectors;

    public void ResetVectors()
    {
        for (int i = 0; i < vectors.Length; i++)
        {
            vectors[i].x = vectors[i].y = vectors[i].z = 0;
        }
    }

    public double GetResults()
    {
        double result = 0;
        for (int i = 0; i < vectors.Length; i++)
        {
            result += vectors[i].x * vectors[i].y * vectors[i].z;
        }
        return result;
    }
}

struct Vector
{
    public double x;
    public double y;
    public double z;
}

struct CalcPoint
{
    public double result;
}
static void Main(字符串[]args)
{
System.Diagnostics.Stopwatch计时器=新的System.Diagnostics.Stopwatch();
timer.Start();
整数=20000;
int numCalpoints=5000;
int vecSize=10000;
CalcPoint[]calcpoints=新的CalcPoint[numCalpoints];
CoefficientVector coeff=新的CoefficientVector();
coeff.vectors=新向量[vecSize];
//不知道如何正确使用Parallel。在这里
//Parallel.For(0,numCalpoints,=>){
对于(int i=0;i
并行。For
方法当前有12个。除了
int
long
ParallelOptions
ParallelState
操作参数的变体之外,您还可以注意到一些具有附加通用参数
TLocal
的变量,如:


如果要重置向量数组中的向量,为什么不使用
array.Clear(…)
?Clear(…)将每个数组元素设置为其默认值。这将在这里起作用,因为结构是值类型,将向量结构设置为其默认值意味着将其每个字段设置为其默认值(对于数字类型为零)…谢谢@elgonzo。也许我解释得不对。但每个计算点都需要保持自己的结果。对和数组使用Parallel.Clear(…)将更改其他计算点的结果。这是正确的吗?对不起,误解了你的问题。只需使用Parallel.Foreach编写代码。不要担心优化。如果您觉得即使使用Parallel.Foreach,您的代码仍然太慢,请分析Parallel.Foreach执行的代码,看看进一步的优化工作会在哪里获得回报。(我假设您在这里给出的代码有点简化,而实际矩阵计算有点复杂)@elgonzo。我喜欢你冷静地对待这一优化——任何严肃的事情:)@elgonzo,正如你所说的。计算实际上是使用矩阵系数进行光线跟踪,而且耗时,这很漂亮。谢谢
public static ParallelLoopResult For<TLocal>(
    int fromInclusive,
    int toExclusive,
    Func<TLocal> localInit,
    Func<int, ParallelLoopState, TLocal, TLocal> body,
    Action<TLocal> localFinally
)
CalcPoint[] calcpoints = new CalcPoint[numCalpoints];

Parallel.For(0, numCalpoints,
    () => new CoefficientVector { vectors = new Vector[vecSize] }, // localInit
    (i, loopState, coeff) => // body
    {
        coeff.ResetVectors();

        //doing some operation on the matrix
        for (int n = 0; n < coeff.vectors.Length; n++)
        {
            coeff.vectors[n].x += n;
            coeff.vectors[n].y += n;
            coeff.vectors[n].z += n;
        }

        calcpoints[i].result = coeff.GetResults();

        return coeff; // required by the body Func signature
    },
    coeff => { } // required by the overload, do nothing in this case
);