当前位置:网站首页>将线程绑定在某个具体的CPU逻辑内核上运行
将线程绑定在某个具体的CPU逻辑内核上运行
2022-06-30 08:36:00 【皓月如我】
据说在运算过程中,逻辑内核的切换会造成额外的开销,影响程序运行效率。最近开始尝试仿真优化(Sim-Opt)方面的研究,刚好需求中涉及这一内容。所以进行了一些尝试。
先上代码:
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Management;
namespace BandThreadToCPU
{
class Program
{
//SetThreadAffinityMask: Set hThread run on logical processer(LP:) dwThreadAffinityMask
[DllImport("kernel32.dll")]
static extern UIntPtr SetThreadAffinityMask(IntPtr hThread, UIntPtr dwThreadAffinityMask);
//Get the handler of current thread
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
//The real function
public static void ChangeValue(object lpIdx)
{
//Bind current thread to a specific logical processer
ulong LpId = SetCpuID((int)lpIdx);
SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(LpId));
// Let program run for a while
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000000; i++)
{
for (int j = 0; j < 1000000; j++)
{
int _data = j;
}
}
stopwatch.Stop();
Console.WriteLine("Running Time: " + stopwatch.ElapsedMilliseconds.ToString());
}
//Get CPU id. index:0 -> id:1, 1->2, 2->4, 3->8, 4->16, ...
static ulong SetCpuID(int lpIdx)
{
ulong cpuLogicalProcessorId = 0;
if (lpIdx < 0 || lpIdx >= System.Environment.ProcessorCount)
{
lpIdx = 0;
}
cpuLogicalProcessorId |= 1UL << lpIdx;
return cpuLogicalProcessorId;
}
static void Main(string[] args)
{
// Specify the cpu logical processor index you want. CPU lp index start from 0
int LOGICAL_PROCESSOR_IDX = 4;
// Get the ManagementClass object
ManagementClass mc = new ManagementClass(new ManagementPath("Win32_Processor"));
// Get the properties in the class
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
PropertyDataCollection properties = mo.Properties;
// Print CPU properties
foreach (PropertyData property in properties)
{
Console.WriteLine( property.Name + ": " + property.Value);
}
}
Stopwatch stopwatch = new Stopwatch();
Thread thread = new Thread(new ParameterizedThreadStart(ChangeValue));
stopwatch.Start();
thread.Start(LOGICAL_PROCESSOR_IDX);
thread.Join();
stopwatch.Stop();
Console.WriteLine("Total running time: " + stopwatch.ElapsedMilliseconds.ToString());
Console.ReadKey();
}
}
}
其中:
SetThreadAffinityMask 将线程和core进行绑定。
GetCurrentThread 获取当前线程的句柄。
ChangeValue 真正的业务运算逻辑放在这里,此处是Demo,所以里面只写了一个很耗时的循环。
SetCpuID 这里是比较有意思的,CPU逻辑处理器索引(index)是从0开始的,但是SetThreadAffinityMask绑定时需要用到的是逻辑处理器的ID,index和id呈2的指数幂关系。即:idx=0对应id=1(2的0次方);idx=3对应id=8(2的3次方)。
运行效果如下,可以看到,04号CPU core已经跑满,但其他core并没有来帮忙。
本篇内容主要参考了jimmy-yang的文章:《C#线程绑定到指定cpu》代码的主要部分也来源于此。主要的修在在于代码的简化,删除了与主要目的无关的部分,并修改了一些变量或函数的命名,修改了注释。使重点内容更加突出,容易理解。
边栏推荐
- [untitled]
- vim 从嫌弃到依赖(21)——跨文件搜索
- 【NVMe2.0b 14-4】Directive Send/Receive command
- Getordefault method of map class
- Unity simple shader
- Codeworks 5 questions per day (1700 for each) - the third day
- 2021-05-17
- 从0开始构建一个瀚高数据库Docker镜像
- mysql基础入门 day3 动力节点[老杜]课堂笔记
- Wechat official account third-party platform development, zero foundation entry. I want to teach you
猜你喜欢

Sword finger offer II 076 The kth largest number in the array (use heap to solve TOPK problem)

Redis design and Implementation (II) | database (deletion strategy & expiration elimination strategy)

Sword finger offer II 075 Array relative sort (custom sort, count sort)

Wikimedia Foundation announces the first customers of its new commercial product "Wikimedia enterprise"

End-to-end 3D Point Cloud Instance Segmentation without Detection

【NVMe2.0b 14-5】Firmware Download/Commit command

Environment configuration of ROS Aubo manipulator

【NVMe2.0b 14-2】Create/Delete Queue

【kotlin 协程】万字协程 一篇完成kotlin 协程进阶

1. Problems related to OpenGL window and environment configuration
随机推荐
14岁懂社会-《关于“工作的幸福”这件事儿》读书笔记
Emoji icons supported by markdown
【NVMe2.0b 14】NVMe Admin Command Set
2021-05-06
我们如何拿到自己满意的薪资呢?这些套路还是需要掌握的
Unity 基础光照模型
vim 从嫌弃到依赖(21)——跨文件搜索
Redis design and Implementation (VI) | cluster (sharding)
swagger使用
Enhance the add / delete operation of for loop & iterator delete collection elements
[data analysis and display]
Be careful of this hole in transmittable thread local
Qqquickpainteditem implements graffiti program drawing board
Cesium learning notes (VI) particle system
layer. Open processing method when the passed value is an array or the value is too long
Rendering engine development
[untitled]
Cesium learning notes (II) uploading data using rest API
Sword finger offer II 076 The kth largest number in the array (use heap to solve TOPK problem)
Cesium learning notes (III) creating instances