我正在尝试使用Parallel.for循环来加速我的进程。我无法完成这项工作,因为我使用的索引超出了界限。在研究了网站之后,我想我知道自己是什么doing wrong,我认为我也是以临时变量的形式找到了解决方案,它在输入代码中的动作之前存储了循环变量。然而,这在我的例子中不起作用。我找到了有人提供给System.Collections.Concurrent的链接,据说可以为这些情况提供安全的线程,但我不知道如何使用该集合。我该怎么做?
我试图创建一个复制粘贴代码供你们运行,但我做错了,这可能表明我的经验不足:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text;
namespace empty
{
class Program
{
double[, , ,] info = new double[100, 100, 10, 5];
void calculate()
{
int row;
int layer, tex_class;
double result;
try
{
for (row = 0; row < 100; row++)
{
Parallel.For(0, 99, col =>
{
int tempcol = col;
for (layer = 0; layer < 10; layer++)
{
int templayer = layer;
for (tex_class = 0; tex_class < 5; tex_class++)
{
int tempclass = tex_class;
result = info[row, tempcol, templayer, tempclass];
}
//other code
}
});
}
}
catch { }
}
static void Main(string[] args)
{
calculate();
}
}
}
答案 0 :(得分:1)
因为循环并行运行,变量layer和tex_class将在不同的线程中增加。这将导致最终超过in指数的值。确保这些变量的范围仅在使用变量的循环内。尽可能减小范围以避免其他线程增加相同的变量。这段代码对我有用:
class Program
{
double[, , ,] info = new double[100, 100, 10, 5];
public void calculate()
{
int row;
double result;
try
{
for (row = 0; row < 100; row++)
{
Parallel.For(0, 99, col =>
{
for (int layer = 0; layer < 10; layer++)
{
for (int tex_class = 0; tex_class < 5; tex_class++)
{
result = info[row, col, layer, tex_class];
}
//other code
}
});
}
}
catch { }
}
}
除此之外,我建议在最外层循环上使用parallel for以尽可能多地平行工作。初始化并行会产生开销,这可能会降低您的性能而不是增加它。这就是我在这里做的事情:
class Program
{
double[, , ,] info = new double[100, 100, 10, 5];
public void calculate()
{
double result;
try
{
Parallel.For(0, 100, row =>
{
for (int col = 0; col < 100; col++)
{
for (int layer = 0; layer < 10; layer++)
{
for (int tex_class = 0; tex_class < 5; tex_class++)
{
result = info[row, col, layer, tex_class];
}
//other code
}
}
});
}
catch { }
}
}
答案 1 :(得分:0)
我认为,您应该使用本地循环变量,因为您的全局图层变量在所有并行线程中都会增加,就像您的tex_class变量一样。
类似的东西:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text;
namespace empty
{
class Program
{
double[, , ,] info = new double[100, 100, 10, 5];
void calculate()
{
try
{
for (int row = 0; row < 100; row++)
{
Parallel.For(0, 99, col =>
{
double result;
int tempcol = col;
for (int layer = 0; layer < 10; layer++)
{
int templayer = layer;
for (int tex_class = 0; tex_class < 5; tex_class++)
{
int tempclass = tex_class;
result = info[row, tempcol, templayer, tempclass];
}
//other code
}
});
}
}
catch { }
}
static void Main(string[] args)
{
calculate();
}
}
}
拇指规则应该是,你的局部变量应该是并行的范围内的本地变量,或者受到某种同步的保护,或者它们将被多个线程同时访问,从而导致不可预测的行为。