[*] Attempt to guess UNIX (Linux) CPU topology when missing file systems

This commit is contained in:
Reece Wilson 2023-08-23 23:23:11 +01:00
parent 3898a41198
commit fae93a71b0
4 changed files with 124 additions and 7 deletions

View File

@ -17,6 +17,9 @@
namespace Aurora::HWInfo
{
static AuUInt32 gGuessedCores {};
static AuUInt32 gGuessedThreads {};
union CPUIdContext
{
struct
@ -349,9 +352,14 @@ namespace Aurora::HWInfo
);
}
AUKN_SYM const CpuInfo &GetCPUInfo()
AuUInt32 GetCPUIDAPICDCores()
{
return gCpuInfo;
return gGuessedCores;
}
AuUInt32 GetCPUIDAPICDThreads()
{
return gGuessedThreads;
}
void SetCpuId()
@ -377,13 +385,42 @@ namespace Aurora::HWInfo
gCpuInfo.cpuId.vendor = vendor;
{
auto regs = cpuid(1);
gGuessedThreads = (regs.ebx >> 16) & 0xff;
}
if (gCpuInfo.cpuId.vendor == "GenuineIntel")
{
gCpuInfo.cpuId.isIntel = true;
auto regs = cpuid(4);
gGuessedCores = ((regs.eax >> 26) & 0x3f) + 1; // DCP cache
if (!gGuessedThreads)
{
gGuessedThreads = gGuessedCores;
}
}
else if (gCpuInfo.cpuId.vendor == "AuthenticAMD")
{
gCpuInfo.cpuId.isAMD = true;
if (!gGuessedCores)
{
auto regs = cpuid(0x80000008);
gGuessedCores = (AuUInt32(regs.ecx) & 0xfful) + 1;
if (!gGuessedThreads)
{
gGuessedThreads = gGuessedCores;
}
}
}
if (!gGuessedCores && gGuessedThreads)
{
gGuessedThreads = gGuessedCores;
}
// load bitset with flags for function 0x00000001

View File

@ -16,6 +16,9 @@
namespace Aurora::HWInfo
{
AuUInt32 GetCPUIDAPICDCores();
AuUInt32 GetCPUIDAPICDThreads();
static AuUInt32 ReadUInt(const AuString &path)
{
AuString contents;
@ -124,6 +127,74 @@ namespace Aurora::HWInfo
gCpuInfo.maskAllCores.Add(cpuId);
}
}
static void SetBasicAPICInformation()
{
if (gCpuInfo.uCores == 1 ||
gCpuInfo.uCores == 0)
{
gCpuInfo.uCores = GetCPUIDAPICDCores();
}
if (!gCpuInfo.uThreads)
{
gCpuInfo.uThreads = GetCPUIDAPICDThreads();
}
else
{
return;
}
if (gCpuInfo.uThreads & 1)
{
for (AU_ITERATE_N(i, gCpuInfo.uThreads))
{
auto mask = 1 << i;
gCpuInfo.maskPCores.SetBit(i);
gCpuInfo.threadTopology.push_back(mask);
CpuBitId coreId;
coreId.lower = mask;
gCpuInfo.coreTopology.push_back(coreId);
gCpuInfo.pCoreTopology.push_back(coreId);
gCpuInfo.maskAllCores.Add(coreId);
}
if (gCpuInfo.uCores == 1 ||
gCpuInfo.uCores == 0)
{
gCpuInfo.uCores = gCpuInfo.uThreads;
}
}
else
{
auto uHalf = gCpuInfo.uThreads / 2;
for (AU_ITERATE_N(i, uHalf))
{
gCpuInfo.maskPCores.SetBit(i);
gCpuInfo.maskPCores.SetBit(i + uHalf);
auto maskA = 1u << i;
auto maskB = 1u << (i + uHalf);
auto maskC = maskA | maskB;
gCpuInfo.threadTopology.push_back(maskA);
gCpuInfo.threadTopology.push_back(maskB);
CpuBitId coreId;
coreId.lower = maskC;
gCpuInfo.coreTopology.push_back(coreId);
gCpuInfo.pCoreTopology.push_back(coreId);
gCpuInfo.maskAllCores.Add(coreId);
}
gCpuInfo.uCores = gCpuInfo.uThreads / 2;
gCpuInfo.bMaskMTHalf = true;
}
}
void SetCpuTopologyLinux()
{
@ -131,9 +202,11 @@ namespace Aurora::HWInfo
SetCpuA();
gCpuInfo.uSocket = AuMax(gCpuInfo.uSocket, AuUInt8(1));
gCpuInfo.uCores = AuMax(gCpuInfo.uCores, AuUInt8(1));
gCpuInfo.uThreads = gCpuInfo.uThreads ?
gCpuInfo.uThreads :
get_nprocs();
if (gCpuInfo.uCores == 1 ||
gCpuInfo.uCores == 0)
{
SetBasicAPICInformation();
}
}
}

View File

@ -294,6 +294,8 @@ namespace Aurora::HWInfo
gCpuInfo.pCoreTopology.push_back(coreId);
gCpuInfo.maskAllCores.Add(coreId);
}
gCpuInfo.uCores = gCpuInfo.uThreads;
}
else
{
@ -322,7 +324,6 @@ namespace Aurora::HWInfo
}
gCpuInfo.uCores = gCpuInfo.uThreads / 2;
gCpuInfo.uThreads = 2;
gCpuInfo.bMaskMTHalf = true;
}

View File

@ -60,4 +60,10 @@ namespace Aurora::HWInfo
SetCpuTopology();
SetFakeTopologyIfMissing();
}
AUKN_SYM const CpuInfo &GetCPUInfo()
{
return gCpuInfo;
}
}