我目前正在尝试改进我正在从事的 C# 项目。具体来说,我的目标是并行化一些操作以减少处理时间。我从小片段开始只是为了掌握它。以下代码(非并行)正常工作(如预期的那样)
for (int i = 0; i < M; i++)
{
double d;
try
{
d = Double.Parse(lData[i]);
}
catch (Exception)
{
throw new Exception("Wrong formatting on data number " + (i + 1) + " on line " + (lCount + 1));
}
sg[lCount % N][i] = d;
}
通过使用以下(并行)代码,我希望获得完全相同的结果,但事实并非如此。
Parallel.For(0, M, i =>
{
double d;
try
{
d = Double.Parse(lData[i]);
}
catch (Exception)
{
throw new Exception("Wrong formatting on data number " + (i + 1) + " on line " + (lCount + 1));
}
sg[lCount % N][i] = d;
});
这些片段来自程序的一部分,从文件中读取数据,一次一行。每行都是逗号分隔的双精度数字序列,我使用 String.Split() 将其放入向量 lData[] 中。每 M 行,数据序列从一个新的数据帧开始(因此% M
在我分配值时在元素索引中)。
我的理解(显然是错误的)是通过将(串行)for循环中的代码放在Parallel.For
我并行执行的第三个参数中。这不应该改变结果。问题在于线程都在访问 lCount 和 M 吗?我应该制作线程本地副本吗?
谢谢。
(因为我是新手,所以不允许创建Parallel.For
标签)
编辑:我进行了更多测试。基本上,我在代码中比以前更早地查看了输出。看来我的代码的并行版本并没有sg[][]
完全填充数组。相反,某些值保留为默认值(在我的情况下为 0)。
编辑2(回答一些评论):
lData[]
是string[]
通过使用获得的string.Split()
。我要拆分的原始字符串是从我的数据文件中读取的。我编写了生成它们的代码,因此它们通常格式正确(我仍然try-catch
出于习惯使用该构造)。就在 for 循环(并行或串行)之前,我检查以验证是否lData[]
具有正确数量的值(M)。如果没有,我会抛出一个异常,阻止程序到达有问题的 for 循环。
sg[][]
是一个 N x M 类型的数组double
(片段中有错字,现在已更正;在我的原始代码中,此错误不存在)。在我从文件中读取 N 行之后,数组sg[][]
包含一个完整的数据集。在 for 循环(并行或串行)之后有一部分 come 如下所示: lCount++; //计算我已经读过的行 if((lCount % N) == 0) { //do things with sg[][] //reset sg[][] } 所以,我故意覆盖所有行sg[][]
. for 循环的全部目的是更新sg[][]
.