win10下,可以在任务管理器里面设置某个进程的线程亲和性,如下图:
然后选择相关的cpu,如下图:
这么做可以使得相关的线程在某些密集型计算任务中只会运行在某些指定的cpu上,以便提高性能。
以下是windwos上c++程序中应用Thread Affinity的示例:
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <bitset>
#include <array>
#include <random>
#include <intrin.h>
#include <windows.h>
namespace threadAffinity
{
std::string getProcessorVendorSerialnumber()
{
std::array<int, 4> cpuInfo;
__cpuid(cpuInfo.data(), 1);
std::ostringstream infoBuf;
infoBuf
<< std::uppercase << std::hex << std::setfill('0')
<< std::setw(8) << cpuInfo.at(3)
<< std::setw(8) << cpuInfo.at(0);
return infoBuf.str();
}
std::string getThisThreadIdWithString()
{
std::stringstream ss;
ss << std::this_thread::get_id();
return ss.str();
}
void proc(void)
{
std::random_device rd{};
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned int> distribute(500, 1000);
using namespace std::chrono_literals;
std::string info = "thread id=" + getThisThreadIdWithString() + ", apply cpu ids: ";
for (auto i = 0; i < 6; ++i)
{
//std::this_thread::sleep_for(1s);
std::this_thread::sleep_for(std::chrono::milliseconds(distribute(gen)));
//std::string info = "thread id=" + getThisThreadIdWithString() + ",cpuid=" + std::to_string(GetCurrentProcessorNumber()) + ", call.\n";
//std::cout << info;
info += std::to_string(GetCurrentProcessorNumber()) + ",";
}
info += "\n";
std::cout << info;
}
void applyThreadAffinity(std::thread& thr, DWORD_PTR inputMask)
{
std::cout << "SetThreadAffinityMask success inputMask: " << std::bitset<32>(inputMask) << "\n";
// thanks: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadaffinitymask
// If the function succeeds, the return value is the thread's previous affinity mask.
// If the function fails, the return value is zero.
DWORD_PTR returnMask = SetThreadAffinityMask(thr.native_handle(), inputMask);
if (returnMask == 0)
{
DWORD dwErr = GetLastError();
std::cerr << "SetThreadAffinityMask failed, GLE=" << dwErr << '\n';
}
else
{
std::cout << "SetThreadAffinityMask success returnMask: " << std::bitset<32>(returnMask) << "\n";
}
}
void testMain()
{
std::cout << "threadAffinity::testMain() begin ...\n";
std::vector<std::thread> threads;
unsigned int i = 0;
threads.emplace_back(proc);
applyThreadAffinity(threads.back(), 0x1);// 0b000001
i++;
threads.emplace_back(proc);
applyThreadAffinity(threads.back(), 0x2);// 0b000010
i++;
threads.emplace_back(proc);
applyThreadAffinity(threads.back(), 0x4);// 0b000100
i++;
threads.emplace_back(proc);
applyThreadAffinity(threads.back(), 0x3);// 0b000011
i++;
for (; i < std::thread::hardware_concurrency(); ++i)
{
threads.emplace_back(proc);
applyThreadAffinity(threads.back(), DWORD_PTR(1) << i);
}
for (auto& t : threads)
t.join();
//
std::cout << "threadAffinity::testMain() end ...\n";
}
}
可能的输出如下所示:
SetThreadAffinityMask success returnMask: 00000000000011111111111111111111
SetThreadAffinityMask success inputMask: 00000000000000100000000000000000
SetThreadAffinityMask success returnMask: 00000000000011111111111111111111
SetThreadAffinityMask success inputMask: 00000000000001000000000000000000
SetThreadAffinityMask success returnMask: 00000000000011111111111111111111
SetThreadAffinityMask success inputMask: 00000000000010000000000000000000
SetThreadAffinityMask success returnMask: 00000000000011111111111111111111
thread id=30096, apply cpu ids: 18,18,18,18,18,18,
thread id=15588, apply cpu ids: 8,8,8,8,8,8,
thread id=25948, apply cpu ids: 7,7,7,7,7,7,
thread id=35928, apply cpu ids: 6,6,6,6,6,6,
thread id=15184, apply cpu ids: 9,9,9,9,9,9,
thread id=6396, apply cpu ids: 0,0,0,0,0,0,
thread id=22032, apply cpu ids: 15,15,15,15,15,15,
thread id=18116, apply cpu ids: 17,17,17,17,17,17,
thread id=23424, apply cpu ids: 11,11,11,11,11,11,
thread id=9556, apply cpu ids: 1,1,1,1,1,1,
thread id=21996, apply cpu ids: 12,12,12,12,12,12,
thread id=30992, apply cpu ids: 14,14,14,14,14,14,
thread id=22372, apply cpu ids: 5,5,5,5,5,5,
thread id=13832, apply cpu ids: 2,2,2,2,2,2,
thread id=31816, apply cpu ids: 16,16,16,16,16,16,
thread id=13332, apply cpu ids: 19,19,19,19,19,19,
thread id=35936, apply cpu ids: 13,13,13,13,13,13,
thread id=27400, apply cpu ids: 0,1,1,0,1,1,
thread id=35172, apply cpu ids: 10,10,10,10,10,10,
thread id=36296, apply cpu ids: 4,4,4,4,4,4,