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