c++中关于Thread Affinity(线程亲和性)示例源码

win10下,可以在任务管理器里面设置某个进程的线程亲和性,如下图:

c++中关于Thread Affinity(线程亲和性)示例源码_第1张图片

然后选择相关的cpu,如下图:

c++中关于Thread Affinity(线程亲和性)示例源码_第2张图片

这么做可以使得相关的线程在某些密集型计算任务中只会运行在某些指定的cpu上,以便提高性能。

以下是windwos上c++程序中应用Thread Affinity的示例:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

namespace threadAffinity
{
std::string getProcessorVendorSerialnumber()
{
    std::array 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 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 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,

你可能感兴趣的:(c++/c/asm,windows,c++,开发语言)