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

本文详细介绍了如何通过手动调节或代码自动调节的方式,将线程绑定到特定的CPU核心,以避免Windows负载均衡功能与Intel SpeedStep技术之间的冲突,从而提高单线程程序的执行效率。通过了解如何获取当前CPU的核心数量和使用SetThreadAffinityMask函数,开发者能够更有效地管理多线程任务,确保关键进程得到充分利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个程序指定到单独一个CPU上运行会比不指定CPU运行时快。这中间主要有两个原因:
1)CPU切换时损耗的性能。
2)Intel的自动降频技术和windows的机制冲突:windows有一个功能是平衡负载,可以将一个线程在不同时间分配到不同CPU,从而使得每一个CPU不“过累”。然而,Inter又有一个技术叫做SpeedStep,当一个CPU没有满负荷运行时自动降频从而达到节能减排的目的。这两个功能实际是冲突的:一个程序被分配到多个CPU协同工作->每个CPU都不是满载->每个CPU都会降频->windows发现每个CPU性能都降低了,因此程序执行速度也降低了。

因此,将线程(进程)绑定到指定CPU核心,从而不让windows自作主张帮我们分散任务,从而提高单线程效率是很有必要的。有两种方法实现绑定进程到指定CPU:
1)手工调节:在资源管理器的进程里面,设置相关性,可以设置进程到某个或者某些指定的CPU核心。
手工指定CPU核心
这种方法最简便,同样是最优效率的,因为你可以根据当前CPU的负载情况进行选择。
2)代码自动调节:
参考:http://www.cnblogs.com/kex1n/archive/2011/05/09/2040924.html
具体函数为:

1
DWORD_PTR SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffinityMask);

其中,第一个参数为线程句柄,第二个参数为一个mask。
如果要知道当前线程的句柄,可以通过函数:GetCurrentThread()得到。否则,在创建多线程的时候,也同样可以得到创建的线程的句柄。
第二个参数为mask,可取值为0~2^31(32位)和0~2^63(64位),每一位代表每一个CPU是否使用。
比如,你要指定进程到第0个CPU上,则mask=0×01
第1个CPU:mask=0×02
第2个CPU:mask=0×04 (注意不是0×03)
第3个CPU:mask=0×08
以此类推。
如果要指定多个CPU:
比如第0、1个:mask=0×03
第1、2个:mask=0×06
以此类推。
如果CPU个数不足,则会进行取模操作。比如一共4个CPU,则mask=0×0010则和0×01一样。
这种方法的好处是多线程时不用每次都手动选择CPU,缺点是万一选到的CPU负载很高,那么程序执行速度就慢了(英雄所见略同所以大家都抢到同一个CPU去了么~~)
效果如下图所示:
指定CPU核心
还有一个实用的函数来获取当前CPU的核心数量:

1
2
3
SYSTEM_INFO info;
GetSystemInfo(&info);
printf("Number of processors: %d.\n", info.dwNumberOfProcessors);

输出的是逻辑核心数量,比如i3处理器就是双核心四线程,输出4。i5处理器是四核心四线程,输出也是4。
这样就可以方便的知道当前系统一共有多少个CPU了,同时也方便了线程数选择。

转自:http://hymike.net/blog/?p=460

在Linux下,使用C语言操作线程并将其绑定到特定CPU核心通常涉及到系统调用`sched_setaffinity`。这个函数允许你设置一个进程线程的亲缘性位集,指定它希望运行在哪些CPU上。以下是一个简单的步骤: 1. 首先,你需要包含头文件`<sched.h>`: ```c #include <sched.h> ``` 2. 确定线程ID,你可以通过`pthread_self()`获取当前线程的ID,或者直接传递给`pthread_t`类型的变量。 3. 创建一个CPU索引数组,`cpuset`结构体描述了你要绑定核心范围。例如,如果你想要将线程绑定到第0和第1两个CPU核心,可以这样做: ```c cpu_set_t cpu_set; CPU_ZERO(&cpu_set); // 初始化一个空的CPU位集 CPU_SET(0, &cpu_set); // 设置CPU 0 CPU_SET(1, &cpu_set); // 设置CPU 1 int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); if (num_cpus <= 0) { perror("sysconf error"); } else { CPU_SET_RANGE(0, num_cpus - 1, &cpu_set); // 设置范围内的所有CPU } ``` 4. 使用`sched_setaffinity`函数实际绑定线程指定CPU集: ```c if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set) != 0) { perror("Failed to set affinity"); } ``` 这里,`pthread_setaffinity_np`用于设置线程的亲缘性,如果返回值非零则表示失败。 请注意,线程绑定到特定CPU核心并不是强制性的,内核可能会根据调度算法自行调整线程。另外,并非所有的处理器都支持这种功能,某些嵌入式设备或老版本的Linux可能不提供此特性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值