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上也给出了对应的例子: ...
随机推荐
- JSON转换为CSV
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> ...
- Oracle PL/SQL 中的 CHAR 和 VARCHAR2 比较
https://docs.oracle.com/cd/B14117_01/appdev.101/b10807/b_char.htm SQL 标准要求被比较的两个字符值具有相等的长度.如果比较中的两个值 ...
- KingbaseES 统计信息收集器没有响应问题分析
统计信息收集器没有响应/Stats collector is not responding 问题现象: kingbase数据库日志提示:统计信息收集器没有响应/Stats collector is n ...
- OPC报文详解
OPC (OLE for Process Control) 是一种工业通讯协议的标准,用于实现不同制造商的设备和系统之间的数据交换.它主要用于工业自动化系统中.OPC标准有几个不同的规范,包括OPC ...
- win10/11 暂停更新
1. win+R 输入regeidt 进入注册表编辑器 2.在"计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Sett ...
- CH395的FTP Server(主动模式)简单应用参考
FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一.FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端.本篇文章将基于FTP协议 ...
- #分块,二分#洛谷 5356 [Ynoi2017] 由乃打扑克
题目 支持区间加和区间查询第 \(k\) 小 分析 分块之后给每个整块排序,这样修改的时候整块打标记,散块直接分开把需要加的部分暴力加之后归并,就是 \(O(\sqrt{n})\) 的 查询的话,如果 ...
- #树链剖分,树上启发式合并#CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
题目 分析 考虑回文串当且仅当最多有一个字母出现奇数次, 可以记录某个二进制状态的最大深度, 一种就是点\(x\)到某个点,另一种就是经过点\(x\)的一条路径 在\(x\)的子树中递归实现,重儿子保 ...
- 使用 OpenCV 进行文档矫正
使用 OpenCV 进行文档矫正 本文只发布于博客园与pchar博客 std::vector<std::vector<cv::Point>> cvhelper::findCor ...
- 使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.
错误详情:使用IDEA直接连接数据库报错:Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' ...