158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#include "XUtils.h"
|
|
|
|
#include <Windows.h>
|
|
#include <QThread>
|
|
|
|
#include <QDebug>
|
|
|
|
namespace XUtils
|
|
{
|
|
|
|
/*
|
|
* XUtils/XCpu
|
|
*/
|
|
int32_t XCpu::m_nRegs[4] = {0};
|
|
|
|
XCpu::XCpu()
|
|
{
|
|
memset(m_nRegs, 0, sizeof(m_nRegs));
|
|
}
|
|
|
|
void XCpu::XCpuID(uint32_t nIndex, int32_t (®s)[4])
|
|
{
|
|
#ifdef _WIN32
|
|
__cpuid((int*)regs, (int)nIndex);
|
|
|
|
#else
|
|
asm volatile
|
|
("cpuid" : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
|
|
: "a"(nIndex), "c"(0));
|
|
// ECX is set to zero for CPUID function 4
|
|
#endif
|
|
}
|
|
|
|
uint32_t XCpu::GetPhysicCoreCount()
|
|
{
|
|
XCpuID(1, m_nRegs);
|
|
|
|
uint32_t nLogicCoreCount = (m_nRegs[1] >> 16) & 0xFF;
|
|
|
|
return nLogicCoreCount;
|
|
}
|
|
|
|
uint32_t XCpu::GetLogicCoreCount()
|
|
{
|
|
return QThread::idealThreadCount();
|
|
|
|
int registers[4] = { 0 }; // 用于存储EAX, EBX, ECX, EDX
|
|
int logical_per_core = 0;
|
|
int logical_per_package = 0;
|
|
int physical_cores = 0;
|
|
|
|
|
|
char szCpuVendor[12] = {0};
|
|
XCpuID(0x0, m_nRegs);
|
|
|
|
((uint32_t*)szCpuVendor)[0] = m_nRegs[1];
|
|
((uint32_t*)szCpuVendor)[1] = m_nRegs[3];
|
|
((uint32_t*)szCpuVendor)[2] = m_nRegs[2];
|
|
|
|
std::string strCpuVendor = std::string(szCpuVendor, 12);
|
|
|
|
if (strCpuVendor == "GenuineIntel")
|
|
{
|
|
XCpuID(0x1, m_nRegs);
|
|
int ncores = ((m_nRegs[1] >> 16) & 0xff);
|
|
|
|
int jj = 0;
|
|
}
|
|
else if (strCpuVendor == "AuthenticAMD")
|
|
{
|
|
int jj = 0;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
XCpuID(1, m_nRegs);
|
|
|
|
int nRegs[4] = {0};
|
|
|
|
nRegs[0] = m_nRegs[0];
|
|
nRegs[1] = m_nRegs[1];
|
|
nRegs[2] = m_nRegs[2];
|
|
nRegs[3] = m_nRegs[3];
|
|
|
|
uint32_t nLogicCoreCount = (m_nRegs[1] >> 16) & 0xFF;
|
|
|
|
return nLogicCoreCount;
|
|
}
|
|
|
|
XCpuBindingManager XCpuBindingManager::m_varXCpuBindingManager;
|
|
|
|
XCpuBindingManager& XCpuBindingManager::GetInstance()
|
|
{
|
|
return m_varXCpuBindingManager;
|
|
}
|
|
|
|
void XCpuBindingManager::Init(uint32_t nMaxCpuCores)
|
|
{
|
|
m_mapCpuCorePool.clear();
|
|
|
|
for (int i = 0; i < nMaxCpuCores; i++)
|
|
{
|
|
m_mapCpuCorePool[i] = false;
|
|
|
|
m_mapCpuCoreThread[i] = 0xffffffff;
|
|
}
|
|
|
|
m_bInit = true;
|
|
}
|
|
|
|
bool XCpuBindingManager::GetBindableCpuCoreIndex(uint32_t& nCpuCoreIndex)
|
|
{
|
|
for (std::map<uint32_t, bool>::iterator iter = m_mapCpuCorePool.begin();
|
|
iter != m_mapCpuCorePool.end();
|
|
++iter)
|
|
{
|
|
if (iter->second == false)
|
|
{
|
|
nCpuCoreIndex = iter->first;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool XCpuBindingManager::BindCpuCore(uint32_t hThread, uint32_t nCpuCoreIndex)
|
|
{
|
|
if (!m_bInit)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
::SetThreadAffinityMask((HANDLE)hThread, pow(2, nCpuCoreIndex));
|
|
|
|
m_mapCpuCorePool[nCpuCoreIndex] = true;
|
|
|
|
m_mapCpuCoreThread[nCpuCoreIndex] = hThread;
|
|
|
|
return true;
|
|
}
|
|
|
|
void XCpuBindingManager::UnbindCpuCore(uint32_t nCpuCoreIndex)
|
|
{
|
|
m_mapCpuCorePool[nCpuCoreIndex] = false;
|
|
|
|
m_mapCpuCoreThread[nCpuCoreIndex] = 0xffffffff;
|
|
}
|
|
|
|
XCpuBindingManager::XCpuBindingManager()
|
|
: m_bInit(false)
|
|
{}
|
|
|
|
}
|