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();
}
}
}
多线程的多核分配问题验证
最新推荐文章于 2024-04-23 16:58:51 发布