我是C#的新手 我正在生成随机数,并将其保存到大小为100万的整数数组中,然后使用单线程在数组中搜索用户输入数字及其出现的位置,然后使用5个线程对其进行搜索。我的处理器有4个核心。 问题:多线程比顺序处理花费更多的时间,我只是想不出为什么要感谢任何帮助。 这是代码。
namespace LAB_2
{
class Program
{
static int[] arr = new int[1000000];
static int counter = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0,c5=0;
static int x = 0;
#if DEBUG
static void Main(string[] args)
{
try
{
//Take input
generate();
Console.WriteLine("Enter number to search for its occurances");
x = Console.Read();
//Multithreaded search
Stopwatch stopwatch2 = Stopwatch.StartNew();
multithreaded_search();
stopwatch2.Stop();
Console.WriteLine("Multithreaded search");
Console.WriteLine("Total milliseconds with multiple threads = " + stopwatch2.ElapsedMilliseconds);
//search without multithreading
Stopwatch stopwatch = Stopwatch.StartNew();
search();
stopwatch.Stop();
Console.WriteLine("Total milliseconds without multiple threads = " + stopwatch.ElapsedMilliseconds);
}
finally
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
#endif
}
public static void generate() //Populate the array
{
Random rnd = new Random();
for (int i = 0; i < 1000000; i++)
{
arr[i] = rnd.Next(1, 500000);
}
}
public static void search() //single threaded/Normal searching
{
int counter = 0;
for (int i = 0; i < 1000000; i++)
{
if (x == arr[i])
{
counter++;
}
}
Console.WriteLine("Number of occurances " + counter);
}
public static void multithreaded_search()
{
Task thr1 = Task.Factory.StartNew(() => doStuff(0, 200000, "c1"));
Task thr2 = Task.Factory.StartNew(() => doStuff(200001, 400000, "c2"));
Task thr3 = Task.Factory.StartNew(() => doStuff(400001, 600000, "c3"));
Task thr4 = Task.Factory.StartNew(() => doStuff(600001, 800000, "c4"));
Task thr5 = Task.Factory.StartNew(() => doStuff(800001, 1000000, "c5"));
//IF I don't use WaitAll then the search is
//faster than sequential, but gets compromised
Task.WaitAll(thr1, thr2, thr3, thr4, thr5);
counter = c1 + c2 + c3 + c4 + c5;
Console.WriteLine("Multithreaded search");
Console.WriteLine("Number of occurances " + counter);
}
static void doStuff(int stime, int etime, String c)
{
for (int i = stime; i < etime; i++)
{
if (x == arr[i])
{
switch (c)
{
case "c1":
c1++;
break;
case "c2":
c2++;
break;
case "c3":
c3++;
break;
case "c4":
c4++;
break;
case "c5":
c5++;
break;
};
}
Thread.Yield();
}
}
}
}
答案 0 :(得分:0)
首先,在doStuff中,您要做的工作要比搜索更多。虽然它不太可能产生明显的效果,但您永远不会知道。
第二,Thread.Yield是执行任务的杀手。当您认为锁可能太昂贵时,该方法旨在用于极少数情况下,例如旋转。在这里,这只是代码的刹车,导致OS调度程序完成更多工作,甚至可能在当前内核上进行上下文切换,从而使缓存无效。
最后,您的数据和计算量很小。现代的CPU会立即枚举这样的数组,它的很大一部分甚至全部都可以放入缓存中。并发处理有其开销。
我推荐Benchmark.NET。