在C#Net 2.0上
代码的工作速度比单线程版本略慢。 xDiff = 2100,yDiff = 2000;单线程几乎14秒,多线程16秒(此代码)。有些事情一定是错的。 我需要填充结果数组。只有一次在数组的节点上写入数据,没有读取因此它应该适合多线程。
double[,] result = new double[xDiff, yDiff];
int threadCount = Environment.ProcessorCount;
ManualResetEvent finished = new ManualResetEvent(false);
int perthread = xDiff / threadCount;
int left = xDiff % threadCount;
int toProcess = threadCount;
int s = 0;
int e = left;
for (int ii = 0; ii < threadCount; ii++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
for (int x = s; x < e; x++)
for (int y = 0; y < yDiff; y++)
{
result[x, y] = DoWork((xStart + x), (yStart + y), p)
}
if (System.Threading.Interlocked.Decrement(ref toProcess) == 0) finished.Set();
}), null);
s = e;
e += perthread;
}
finished.WaitOne();
return result;
xStart,yStart是double,p是一个大类。 DoWork函数只调用p的某些函数,但不会在类上写入/更改任何数据。
简要结果[x,y] = DoWork((xStart + x),(yStart + y),p); 我需要尽可能快地填充阵列。我该怎么办?
答案 0 :(得分:2)
我认为这里的问题是变量s
和e
是在线程外修改的闭包,因此线程获取的值不正确并使用了不正确的范围。
要查看是否属于这种情况,请尝试添加Console.WriteLine()
或Trace.WriteLine()
以打印出帖子中s
和e
的值(在调用之后) QueueUserWorkItem()
)看看这是不是正在发生的事情。
要解决此问题,请将修改后的闭包复制到临时变量中并使用线程中的变量,如下所示:
for (int ii = 0; ii < threadCount; ii++)
{
int ts = s; // Copy them outside the loop.
int te = e;
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
for (int x = ts; x < te; x++) // Use the copy here.