CPU亲缘性(CPU Affinity)是指将线程或进程固定到特定的CPU核心上运行的能力。这种做法可以减少上下文切换,提高缓存利用率,从而提升性能。
原理
- 缓存局部性: 当线程在同一个CPU上运行时,它可以利用该CPU的缓存,减少内存访问延迟。频繁切换CPU会导致缓存失效,从而影响性能。
- 减少上下文切换: 通过将线程绑定到特定CPU,可以减少操作系统在不同核心之间频繁调度的情况。
- 热插拔支持: 在支持热插拔的系统中,CPU亲缘性可以确保线程不会在不必要的情况下迁移到新加入的CPU上。
实现
在不同的平台上设置CPU亲缘性的方法可能有所不同。在Linux中,使用pthread_setaffinity_np
函数,而在Windows中,使用SetThreadAffinityMask
函数。
linux下实现(c++)
以下是一个使用POSIX线程(pthread)库在Linux上设置CPU亲缘性的示例代码:
#include <iostream>
#include <thread>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
void thread_function(int cpu_id) {
// 设置线程亲缘性
cpu_set_t cpuset;
CPU_ZERO(&cpuset); // 清空CPU集
CPU_SET(cpu_id, &cpuset); // 将目标CPU添加到CPU集
// 获取当前线程ID
pthread_t current_thread = pthread_self();
// 设置亲缘性
if (0 != pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset)) {
std::cerr << "Error setting CPU affinity\n";
return;
}
// 线程执行的任务
std::cout << "Thread running on CPU " << cpu_id << std::endl;
// 模拟工作
for (int i = 0; i < 5; ++i) {
std::cout << "Thread " << cpu_id << " working...\n";
usleep(500000); // 休眠500毫秒
}
}
int main() {
const int num_threads = 4;
std::thread threads[num_threads];
// 创建多个线程,每个线程绑定到不同的CPU
for (int i = 0; i < num_threads; ++i) {
threads[i] = std::thread(thread_function, i);
}
// 等待所有线程完成
for (auto& th : threads) {
th.join();
}
return 0;
}
代码解析
- 头文件: 引入了所需的头文件,包括
<pthread.h>
和<sched.h>
,用于线程和CPU调度。 - 线程函数:
- 创建并清空一个
cpu_set_t
类型的变量。 - 使用
CPU_SET
宏将目标CPU添加到CPU集。 - 获取当前线程的ID,并调用
pthread_setaffinity_np
设置线程亲缘性。 - 在控制台输出当前线程运行的CPU ID。
- 创建并清空一个
- 主函数: 创建多个线程,每个线程都绑定到不同的CPU上。
windows下实现(c++)
在Windows上,设置CPU亲缘性的方法如下:
#include <iostream>
#include <thread>
#include <windows.h>
void thread_function(int cpu_id) {
// 设置线程亲缘性
HANDLE current_thread = GetCurrentThread();
DWORD_PTR mask = 1 << cpu_id;
if (0 == SetThreadAffinityMask(current_thread, mask)) {
std::cerr << "Error setting CPU affinity\n";
return;
}
std::cout << "Thread running on CPU " << cpu_id << std::endl;
// 模拟工作
for (int i = 0; i < 5; ++i) {
std::cout << "Thread " << cpu_id << " working...\n";
Sleep(500); // 休眠500毫秒
}
}
int main() {
const int num_threads = 4;
std::thread threads[num_threads];
// 创建多个线程,每个线程绑定到不同的CPU
for (int i = 0; i < num_threads; ++i) {
threads[i] = std::thread(thread_function, i);
}
// 等待所有线程完成
for (auto& th : threads) {
th.join();
}
return 0;
}
总结
CPU亲缘性是优化多线程程序性能的重要手段,能够提高缓存效率并减少上下文切换。根据操作系统的不同,使用不同的方法来实现亲缘性。在Linux上使用pthread_setaffinity_np
,而在Windows上使用SetThreadAffinityMask
。通过合理设置线程的CPU亲缘性,可以显著提升程序的性能。