Windows下绑定线程到指定的CPU核心
在某些场景下,需要把程序绑定到指定CPU核心提高执行效率。通过微软官方文档查询到Windows提供了两个Win32函数:SetThreadAffinityMask和SetProcessAffinityMask 为指定线程和进程设置处理器关联掩码。通俗的讲就是在指定的CPU核心上执行线程或者进程。
这里的CPU核心指的是逻辑核心,而非物理核心。
SetThreadAffinityMask
SetThreadAffinityMask函数定义
SetThreadAffinityMask的定义如下:
DWORD_PTR SetThreadAffinityMask(
[in] HANDLE hThread,
[in] DWORD_PTR dwThreadAffinityMask
);
从函数的定义看需要传递两个参数:
- hThread:指向要设置处理器关联的线程句柄。如果是想设置当前线程的关联掩码,可以使用 GetCurrentThread() 函数获取句柄。
- dwThreadAffinityMask:处理器的关联掩码。是一个DWORD_PTR类型的值,长度共8个字节(64bit),每一bit代表一个cpu核。
如果需要支持超过64核的CPU时,则需要使用SetThreadGroupAffinity函数
为了更清晰的表达dwThreadAffinityMask的含义,下边用二进制数表示该值。比如,需要把线程绑定到
第0个核:则dwThreadAffinityMask=0B_0001;(0x01)
第1个核:则dwThreadAffinityMask=0B_0010;(0x02)
第2个核:则dwThreadAffinityMask=0B_0100;(0x04)
第3个核:则dwThreadAffinityMask=0B_1000;(0x08)
……
如果要绑定到多个cpu核心,比如绑定到第1和2个cpu核时,dwThreadAffinityMask=0B_0110,对应的十六进制数也就是0x06。
调用示例
首先引入Win32API
[DllImport("kernel32.dll")]
static extern UIntPtr SetThreadAffinityMask(IntPtr hThread, UIntPtr dwThreadAffinityMask);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
由于dwThreadAffinityMask的值是按照$2^n$的指数递增,与通常习惯指定第n个核心不符,并且不同的设备CPU核心数不一样,指定CPU核心时可能超出CPU核心数量,因此可以对指定CPU核心做个简单的处理:
static ulong SetCpuID(int lpIdx)
{
ulong cpuLogicalProcessorId = 0;
if (lpIdx < 0 || lpIdx >= System.Environment.ProcessorCount)
{
lpIdx = 0;
}
//通过移位运算转换lgidx->dwThreadAffinityMask:0->1,1->2,2->4,3->8,……
cpuLogicalProcessorId |= 1UL << lpIdx;
return cpuLogicalProcessorId;
}
接下来就可以进行测试了
ulong LpId = SetCpuID((int)lpIdx);
SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(LpId));
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("运行时间: " + stopwatch.ElapsedMilliseconds.ToString());
效果如图如下:

SetProcessAffinityMask
SetProcessAffinityMask与SetThreadAffinityMask非常相似,不同的是其作用于整个进程,可以决定进程内的所有线程共同运行在指定的处理器上。
函数定义如下:
BOOL SetProcessAffinityMask(
[in] HANDLE hProcess,
[in] DWORD_PTR dwProcessAffinityMask
);
和SetThreadAffinityMask一样,也是需要传递两个参数,只不过第一个参数传递的是线程的句柄。
小结
在某些场景可以通过SetThreadAffinityMask和SetProcessAffinityMask 提高程序执行效率,主要是基于以下几个原因:
- 提高性能:通过将线程绑定到特定的处理器,可以减少线程在不同处理器之间的切换开销,尤其是在多核系统中,有助于提升程序的执行效率。
- 避免缓存抖动:确保线程始终在同一个处理器上运行,可以减少缓存未命中,因为相关的数据更可能保留在该处理器的高速缓存中。
- 实时系统和并发控制:在需要严格控制线程执行位置的场景下,比如实时系统或者某些并发控制策略中,通过设定处理器关联可以满足特定的调度需求。
需要注意的是,SetThreadAffinityMask和SetProcessAffinityMask并不是独占CPU核心,如果关联的CPU核心本身负载就很高,这个时候程序执行效率反而会降低。
Windows下绑定线程到指定的CPU核心的更多相关文章
- windows下绑定线程(进程)到指定的CPU核心
一个程序指定到单独一个CPU上运行会比不指定CPU运行时快.这中间主要有两个原因:1)CPU切换时损耗的性能.2)Intel的自动降频技术和windows的机制冲突:windows有一个功能是平衡负载 ...
- SetThreadAffinityMask windows下绑定线程(进程)到指定的CPU核心
原帖地址:https://www.cnblogs.com/lvdongjie/p/4476766.html 一个程序指定到单独一个CPU上运行会比不指定CPU运行时快.这中间主要有两个原因:1)CPU ...
- WINDOWS下绑定ARP绑定网关
一.WINDOWS下绑定ARP绑定网关步骤一:在能正常上网时,进入MS-DOS窗口,输入命令:arp -a,查看网关的IP对应的正确MAC地址, 并将其记录下来.注意:如果已经不能上网,则先运行一次命 ...
- windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码
我的一个java程序偶尔会出现cpu占用很高的情况 一直不知道什么原因 今天终于抽时间解决了 系统是win2003 jvisualvm 和 jconsole貌似都只能看到总共占用的cpu 看不到每个线 ...
- windows下揪出java程序占用cpu很高的线程
背景 天天搞java,这些监控也都知道,用过,但也没往细里追究.因为也没碰见这种问题,这次还是静下来走一遍流程吧.与网上基本一致,不过我区分了下linux和windows的不一样.我感觉基本是程序写成 ...
- Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity) 转
硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能.现在的服务器上动不动就是多 CPU 多核. ...
- Windows下caffe安装详解(仅CPU)
本文大多转载自 http://blog.csdn.net/guoyk1990/article/details/52909864,加入部分自己实战心得. 1.环境:windows 7\VS2013 2. ...
- windows下多Python环境指定pip安装模块到对应Python环境下
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿在windows下装了2套Python,一套是直接安装的Pytho ...
- Windows下POSIX线程编程(pThread)环境搭建
系统: Windows 编辑器:codeblocks13.12 1. 简介: Windows有一个叫 POSIX Threads for Win32 的开源项目给出了一个功能比较完善的Windows下 ...
- windows下利用线程池完成多任务的分配和运行
在做项目的过程中有时候为了提升效率,用了多线程的方法来对任务进行分割和应用,后来发现,采用线程池的方法能更好的利用线程资源来计算任务,网上有很多关于如何运行线程池的例子,msdn上也给出了对应的例子: ...
随机推荐
- 那位拿了多个Offer的大佬分享了最新Go面经
和大家分享一下我们 Go就业训练营 和 升职加薪星球 中战友们投稿的真实面经. 这是第一篇,计划还会再更新4篇最新Go面经,都是拿到Offer的那种! 欢迎大家关注我的账号,关注之后不迷路. 先秀战绩 ...
- KingbaseES 如何查看表的创建时间
前言 在oracle数据库中,我们可以查看数据字典dba_objects得到表的创建时间.在Kingbase中如何查看表的创建时间呢?Kingbase数据库中无法通过数据字典查看有关信息,但可以通过其 ...
- 第十三届蓝桥杯大赛软件赛省赛【Java 大学B 组】试题C: 字符统计
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String args[]) { 5 Sca ...
- 【已解决】linux安装mysql依赖包(mysql-community-common-5.7.35-1.el7.x86_64)冲突
错误信息: 软件包 mysql-community-common-5.7.35-1.el7.x86_64 (比 mysql-community-common-5.7.28-1.el7.x86_64 还 ...
- SQL 递归核心思想(递归思维)
目前很缺递归思维,主要是算法代码写得少,本篇记录下以 PostgreSQL 代码举例(主要是非常喜欢这款性能小钢炮数据库). 树状查询不多说,很简单大家基本都会,主要讲 cte 代码递归实现不同需求. ...
- #树状数组#洛谷 4113 [HEOI2012]采花
题目 分析 与HH的项链类似 离线处理询问,按右端点排序,维护最近的颜色和第二近的颜色,修改以第二近的颜色为准 换句话说,若最近颜色的位置为\(pos2\),第二近颜色的位置为\(pos1\) 加入一 ...
- #Splay#洛谷 1486 [NOI2004]郁闷的出纳员
题目 分析 考虑加减工资直接打标记,查询第\(k\)多可以用平衡树, 删除有点恶心,这里考虑Splay,将需要删除的部分的后继splay到根节点并将左子树断边 代码 #include <cstd ...
- JDK14的新特性:JFR,JMC和JFR事件流
目录 简介 JFR JMC 创建JFR 分析JFR JFR事件 JFR事件流 总结 JDK 14的新特性:JFR,JMC和JFR事件流 简介 Java Flight Recorder(JFR)是JVM ...
- OpenHarmony 官网文档有哪些上新?下篇:设备开发文档上新
为了方便社区开发者更易获取 OpenAtom OpenHarmony(以下简称"OpenHarmony")相关文档,暨上篇应用开发文档上新内容,SIG Docs 小组同步准备了设 ...
- Windows wsl2支持systemd
背景 很多Linux发行版都是使用systemd来管理程序进程,但是在WSL中默认是用init来管理进程的. 为了符合长久的使用习惯,且省去不必要的学习成本,就在WSL的发行版(我这里安装的是Ubun ...