C# 为什么单线程代码比多线程代码快?
我写了一个代码,它以单线程和多线程的方式执行求和函数,如下所示:C# 为什么单线程代码比多线程代码快?,c#,multithreading,C#,Multithreading,我写了一个代码,它以单线程和多线程的方式执行求和函数,如下所示: using System; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; namespace ParallelFor { class Program { static void Main() { Console.WriteLine("Progra
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ParallelFor
{
class Program
{
static void Main()
{
Console.WriteLine("Program started");
var step_time = Stopwatch.StartNew();
step_time.Start();
double R1 = 0.0;
double R2 = 0.0;
double R3 = 0.0;
var t1 = new Thread(() => TestCounter(2000, ref R1, 1));
var t2 = new Thread(() => TestCounter(2000, ref R2, 2));
var t3 = new Thread(() => TestCounter(2000, ref R3, 3));
t1.Start();
t2.Start();
t3.Start();
do
{
} while (t1.IsAlive == true || t2.IsAlive == true || t3.IsAlive == true);
Console.WriteLine("inside R1: {0}", R1);
Console.WriteLine("inside R2: {0}", R2);
Console.WriteLine("inside R3: {0}", R3);
Console.WriteLine("Program finished");
step_time.Stop();
Console.WriteLine("multi-thread last {0} (MilSec)\n", step_time.ElapsedMilliseconds);
step_time.Reset();
step_time.Start();
R1 = 0.0;
R2 = 0.0;
R3 = 0.0;
TestCounter(2000, ref R1, 1);
TestCounter(2000, ref R2, 2);
TestCounter(2000, ref R3, 3);
Console.WriteLine("inside R1: {0}", R1);
Console.WriteLine("inside R2: {0}", R2);
Console.WriteLine("inside R3: {0}", R3);
step_time.Stop();
Console.WriteLine("single thread last {0} (MilSec)\n", step_time.ElapsedMilliseconds);
Console.ReadLine();
}
static void TestCounter(int counter, ref double result, int No)
{
for (int i = 0; i < counter + 1; i++)
for (int j = 0; j < counter; j++)
for (int k = 0; k < counter; k++)
result += (double)i;
}
}
}
我发现,单螺纹部分,最后更短!
我用计数器=10000运行代码,结果是一样的!
为什么单线程PAR运行得更快 我认为设置线程并等待线程完成的开销要高于在多个线程上运行代码的收益。 此外,如果启动的线程数超过可用的内核数,则由于上下文切换太多,代码速度会减慢 您可以尝试的一个优化是使用Monitor.Wait调用摆脱手动同步。您可以手动创建尽可能多的线程对象,启动它们,然后通过调用Thread.Join等待线程完成。这样,线程中就不需要任何同步代码:
Thread[] threads = new Thread[NumCores];
for (int i = 0; i < NumCores; i++)
{
threads[i] = new Thread(MyThread);
threads[i].Start(threadData);
}
for (int i = 0; i < NumCores; i++){
threads[i].Join();
}
问题很可能是这样的。我将TestCounter方法更改为以下内容:
static void TestCounter(int counter, ref double result, int No)
{
double internalResult = 0;
for (int i = 0; i < counter + 1; i++)
for (int j = 0; j < counter; j++)
for (int k = 0; k < counter; k++)
internalResult += (double)i;
result += internalResult;
}
在这里,值首先累加到局部变量中,最后写入传递的结果变量。因此,线程大部分时间都在其本地堆栈上工作,而不是在内存位置(也可由其他线程访问的缓存线)上工作
通过这一更改,我几乎获得了预期因子3的加速。您不应该将线程的开始计算为并行持续时间的一部分……首先,您不应该使用while Thread.IsAlive循环,而应该使用Thread.Join或其他更好的方法来等待所有线程完成。第二,你在什么CPU/硬件上运行这个,这对并行线程的性能很重要