我有一个执行矩阵乘法的程序。我有多线程和单线程版本。多线程版本比单线程慢,我不知道为什么。你能解释一下吗?
多线程(大小= 128,秒表显示 5 秒):
private static SemaphoreSlim semaphore = new SemaphoreSlim(size, size);
(...)
for (int i = 0; i < size; i++)
{
threads[i] = new Thread(() => Multiply(ref a, ref b, ref c));
threads[i].Name = i.ToString();
threads[i].Start();
}
for (int i = 0; i < size; i++)
threads[i].Join();
(...)
public static void Multiply(ref float[,] a, ref float[,] b, ref float[,] c)
{
int index = int.Parse(Thread.CurrentThread.Name);
semaphore.Wait();
for (int j = 0; j < c.GetLength(0); j++)
for (int k = 0; k < c.GetLength(0); k++)
c[index, j] += a[index, k] * b[k, j];
semaphore.Release();
}
单线程(尺寸= 128,秒表显示 3 秒):
for (int i = 0; i < size; i++)
Multiply(i, ref a, ref b, ref c);
(...)
public static void Multiply(int i, ref float[,] a, ref float[,] b, ref float[,] c)
{
for (int j = 0; j < c.GetLength(0); j++)
for (int k = 0; k < c.GetLength(0); k++)
c[i, j] += a[i, k] * b[k, j];
}
答案 0 :(得分:4)
这并不罕见。线程,特别是线程同步,往往会增加很多开销。这就是为什么多线程是你仔细考虑的原因,以及为什么异步但不是多线程方法通常是正确的答案。
如果你正在执行CPU繁重的任务,通常最好在一个或少量的工作线程上执行它们,这样它们就不会直接抢占彼此不间断的任务。通常,一旦CPU限制线程的数量超过处理器的可用内核,就没有性能提升 - 实际上是性能损失。
想象一下,试图让一个充满幼儿园的孩子通过一扇门去休息。实际上,将它们排成一行并以有序的方式完成它们比让它们全部相互推开并争取首先通过它更快。即使在你的线程争夺CPU时间之前,如果在线程和线程上花费更多时间,线程仍然会减慢你的速度。通过并行化任务获得的同步开销。
答案 1 :(得分:0)
多线程并不总是比单线程更快。创建线程和同步的额外偷听可能会显着影响完成问题所需的时间。还有其他一些因素可能会对多线程产生影响,比如你的CPU有多少个核心(多线程性能最差)。