在某些场景下,需要把程序绑定到指定CPU核心提高执行效率。通过微软官方文档查询到Windows提供了两个Win32函数:SetThreadAffinityMaskSetProcessAffinityMask 为指定线程和进程设置处理器关联掩码。通俗的讲就是在指定的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一样,也是需要传递两个参数,只不过第一个参数传递的是线程的句柄。

小结

在某些场景可以通过SetThreadAffinityMaskSetProcessAffinityMask 提高程序执行效率,主要是基于以下几个原因:

  • 提高性能:通过将线程绑定到特定的处理器,可以减少线程在不同处理器之间的切换开销,尤其是在多核系统中,有助于提升程序的执行效率。
  • 避免缓存抖动:确保线程始终在同一个处理器上运行,可以减少缓存未命中,因为相关的数据更可能保留在该处理器的高速缓存中。
  • 实时系统和并发控制:在需要严格控制线程执行位置的场景下,比如实时系统或者某些并发控制策略中,通过设定处理器关联可以满足特定的调度需求。

    需要注意的是,SetThreadAffinityMask和SetProcessAffinityMask并不是独占CPU核心,如果关联的CPU核心本身负载就很高,这个时候程序执行效率反而会降低。

Windows下绑定线程到指定的CPU核心的更多相关文章

  1. windows下绑定线程(进程)到指定的CPU核心

    一个程序指定到单独一个CPU上运行会比不指定CPU运行时快.这中间主要有两个原因:1)CPU切换时损耗的性能.2)Intel的自动降频技术和windows的机制冲突:windows有一个功能是平衡负载 ...

  2. SetThreadAffinityMask windows下绑定线程(进程)到指定的CPU核心

    原帖地址:https://www.cnblogs.com/lvdongjie/p/4476766.html 一个程序指定到单独一个CPU上运行会比不指定CPU运行时快.这中间主要有两个原因:1)CPU ...

  3. WINDOWS下绑定ARP绑定网关

    一.WINDOWS下绑定ARP绑定网关步骤一:在能正常上网时,进入MS-DOS窗口,输入命令:arp -a,查看网关的IP对应的正确MAC地址, 并将其记录下来.注意:如果已经不能上网,则先运行一次命 ...

  4. windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码

    我的一个java程序偶尔会出现cpu占用很高的情况 一直不知道什么原因 今天终于抽时间解决了 系统是win2003 jvisualvm 和 jconsole貌似都只能看到总共占用的cpu 看不到每个线 ...

  5. windows下揪出java程序占用cpu很高的线程

    背景 天天搞java,这些监控也都知道,用过,但也没往细里追究.因为也没碰见这种问题,这次还是静下来走一遍流程吧.与网上基本一致,不过我区分了下linux和windows的不一样.我感觉基本是程序写成 ...

  6. Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity) 转

    硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能.现在的服务器上动不动就是多 CPU 多核. ...

  7. Windows下caffe安装详解(仅CPU)

    本文大多转载自 http://blog.csdn.net/guoyk1990/article/details/52909864,加入部分自己实战心得. 1.环境:windows 7\VS2013 2. ...

  8. windows下多Python环境指定pip安装模块到对应Python环境下

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿在windows下装了2套Python,一套是直接安装的Pytho ...

  9. Windows下POSIX线程编程(pThread)环境搭建

    系统: Windows 编辑器:codeblocks13.12 1. 简介: Windows有一个叫 POSIX Threads for Win32 的开源项目给出了一个功能比较完善的Windows下 ...

  10. windows下利用线程池完成多任务的分配和运行

    在做项目的过程中有时候为了提升效率,用了多线程的方法来对任务进行分割和应用,后来发现,采用线程池的方法能更好的利用线程资源来计算任务,网上有很多关于如何运行线程池的例子,msdn上也给出了对应的例子: ...

随机推荐

  1. 百度文库内容复制 C# webbrowser+Nsoup

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. Python - inspect 模块的简单使用

    Python中的inspect模块解析 Python的inspect模块是一个强大的内省工具,允许开发者检查(inspect)活动对象和源代码.它提供了一系列函数,用于获取信息关于正在运行的程序和调用 ...

  3. 给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。

    private static void stringSubLen(String msg) { int max = 0; int left = 0; Map<Character,Integer&g ...

  4. KingbaseES生成动态SQL

    1. 动态SQL 动态SQL在程序启动时会根据输入参数替换相应变量.使用动态SQL可以创建更强大和灵活的应用程序,但在编译时SQL语句的全文不确定,因此运行时编译会牺牲一些性能.动态SQL可以是代码或 ...

  5. KingbaseES 服务器运行参数配置

    Kingbase 服务器运行参数配置 说明: KingbaseES 数据库中,服务器运行参数配和需改有多种方式和注意事项,根据不同的分类配置,修改配置方式不同.关于服务器参数分类请参照[Kingbas ...

  6. win10/11 暂停更新

    1. win+R 输入regeidt 进入注册表编辑器 2.在"计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Sett ...

  7. Mysql Order 排序的时候占用很长时间解决思路

    MySQL中的连表查询(JOIN)在进行ORDER BY排序时可能会变得很慢,尤其是当处理大量数据时.以下是一些优化策略,可以帮助减少排序操作的时间: 索引优化: 确保参与排序的列上有索引.如果排序的 ...

  8. 开发人员使用HANA交付业务的学习路径

    本文于2019年7月22日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 入门 编程规范. 开发环境使用方法. 基本语法,与其它同类软件的 ...

  9. [HAOI2007,P2216,BZOJ1047]理想的正方形单调队列解法

    题目描述 有一个 \(a \times b\) 的整数组成的矩阵,现请你从中找出一个 \(n \times n\) 的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入格式 第一行为 \( ...

  10. C++ 多线程编程和同步机制:详解和实例演示

    C++中的多线程编程和同步机制使得程序员可以利用计算机的多核心来提高程序的运行效率和性能.本文将介绍多线程编程和同步机制的基本概念和使用方法. 多线程编程基础 在C++中,使用<thread&g ...