C# · 12月 30, 2021

C#并行线程代码性能

我一直在测试System.Threading.Parallel和一个线程的性能,我很惊讶地看到并行花费更长的时间完成任务比线程.我确定这是由于我对Parallel的知识有限,我刚刚开始阅读.

我以为我会分享几个片段,如果有人可以指出我的paralle代码运行速度比线程代码慢.还试图运行相同的比较找到素数,发现并行代码完成比线程代码晚.

public class ThreadFactory{ int workersCount; private List<Thread> threads = new List<Thread>(); public ThreadFactory(int threadCount,int workCount,Action<int,int,string> action) { workersCount = threadCount; int totalWorkLoad = workCount; int workLoad = totalWorkLoad / workersCount; int extraLoad = totalWorkLoad % workersCount; for (int i = 0; i < workersCount; i++) { int min,max; if (i < (workersCount – 1)) { min = (i * workLoad); max = ((i * workLoad) + workLoad – 1); } else { min = (i * workLoad); max = (i * workLoad) + (workLoad – 1 + extraLoad); } string name = “Working Thread#” + i; Thread worker = new Thread(() => { action(min,max,name); }); worker.Name = name; threads.Add(worker); } } public void StartWorking() { foreach (Thread thread in threads) { thread.Start(); } foreach (Thread thread in threads) { thread.Join(); } }}

这是程序:

Stopwatch watch = new Stopwatch();watch.Start();int path = 1;List<int> numbers = new List<int>(Enumerable.Range(0,10000));if (path == 1){ Parallel.ForEach(numbers,x => { Console.WriteLine(x); Thread.Sleep(1); });}else{ ThreadFactory workers = new ThreadFactory(10,numbers.Count,(min,text) => { for (int i = min; i <= max; i++) { Console.WriteLine(numbers[i]); Thread.Sleep(1); } }); workers.StartWorking();}watch.Stop();Console.WriteLine(watch.Elapsed.TotalSeconds.ToString());Console.ReadLine();

更新:

考虑到锁定:我尝试了以下代码段.同样的结果,Parallel似乎完成得比较慢.

path = 1;
cieling = 10000000;

List<int> numbers = new List<int>(); if (path == 1) { Parallel.For(0,cieling,x => { lock (numbers) { numbers.Add(x); } }); } else { ThreadFactory workers = new ThreadFactory(10,text) => { for (int i = min; i <= max; i++) { lock (numbers) { numbers.Add(i); } } }); workers.StartWorking(); }

更新2:
只是一个快速更新,我的机器有四核处理器.所以Parallel可以有4个内核.

解决方法 我想我可以回答你的问题.首先,你没有写出你的系统有多少核心.如果你正在运行一个双核,只有4个线程将使用Parallel.For工作,而你在线程示例中使用10个线程.更多的线程会更好的工作,因为你正在运行的任务(打印短睡眠)是一个非常短的任务,线程和线程开销是非常大的任务相比,我几乎可以肯定,如果你编写相同的代码没有线程将工作更快.

两种方法的工作原理相同,但是如果您先创建所有线程,则可以将Parallels分配给Parallel.For使用任务池来添加一些移动开销.