多线程的多核分配问题验证
using System.Diagnostics; using System; using System.Threading.Tasks; namespace THREADS { class Threads { public double[] times = new double[4]; public int[] counts = new int[] { 40000000, 50000000, 70000000 }; /*** * 测试验证 * 1,当一个进程有多个线程时,操作系统会自动将线程分配到不同的CPU上,最优化分配 */ public void Start() { var sw = new Stopwatch(); var tasks = new Task[4]; /*** * Step1,创建四个线程,(使用 new Thread是等效的) */ //测试1,三个线程,每个线程跑一个任务 tasks[0] = new Task(() => { DoTask(counts[0]); times[0] = sw.ElapsedMilliseconds; }); tasks[1] = new Task(() => { DoTask(counts[1]); times[1] = sw.ElapsedMilliseconds; }); tasks[2] = new Task(() => { DoTask(counts[2]); times[2] = sw.ElapsedMilliseconds; }); //测试2,一个线程跑三个任务 tasks[3] = new Task(() => { DoTask(counts[0]); DoTask(counts[1]); DoTask(counts[2]); times[3] = sw.ElapsedMilliseconds; }); /*** * Step2,开启测试线程 */ //PrintProcessInfo("测试线程开启前"); 开启会使t4时间反而变短了,原因不明 //BindThreadToCpu(0); 在此位置绑定是无效的,因为我们的测试线程还没开启,无法将它们都绑定到某个核上 sw.Start(); tasks[0].Start(); tasks[1].Start(); tasks[2].Start(); tasks[3].Start(); /*** * Step3,绑定所有线程到某个核上 * 可以发现,绑定后所有线程的运算时间都明显加长了,因为它们共用一个CPU(debug模式效果更明显,release模式在数据量小时不明显) */ long bindtime = 0; if (true) { var tsw = Stopwatch.StartNew(); var t0 = tsw.ElapsedMilliseconds; BindThreadToCpu(0); //在此位置绑定是有效的,因为我们的测试线程已经开启,可以将它们都绑定到某个核上 bindtime = tsw.ElapsedMilliseconds - t0; } /*** * Step4,等待所有线程结束打印运行时间 */ //PrintProcessInfo("测试线程开启后"); Task.WaitAll(tasks); Console.WriteLine($"time1:{times[0]}, time2:{times[1]}, time3:{times[2]}, time4:{times[3]}, bindtime:{bindtime}"); } private void DoTask(int n) { double sum = 9999999999; for (int i = 0; i < n; i++) { sum /= (i + 1)*(i+1); } } private void PrintProcessInfo(string info) { var p = Process.GetCurrentProcess(); var threads = p.Threads; Console.WriteLine($"{info}:当前进程共有{threads.Count}个线程"); } private void BindThreadToCpu(int core) { var p = Process.GetCurrentProcess(); var threads = p.Threads; if (core >= 0) { for (int i = 0; i < threads.Count; i++) { var item = threads[i]; //将线程绑定到某个核上 item.ProcessorAffinity = (IntPtr)(core + 1); item.IdealProcessor = core; } } } } class Program { static void Main(string[] args) { new Threads().Start(); Console.WriteLine($"执行完成,按任意键结束"); Console.Read(); } } }