mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-05-16 21:00:14 +00:00
### Description <!-- Describe your changes. --> See #19921 Just to address one comment: https://github.com/microsoft/onnxruntime/pull/19921#discussion_r1543398640 since this is an external branch. need to open another pull request for this. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> --------- Co-authored-by: Sai Kishan Pampana <sai.kishan.pampana@intel.com> Co-authored-by: rachguo <rachguo@rachguos-Mini.attlocal.net> Co-authored-by: Jian Chen <cjian@microsoft.com>
110 lines
3.2 KiB
C++
110 lines
3.2 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
#include "lib/Api/pch/pch.h"
|
|
|
|
#include "HardwareCoreEnumerator.h"
|
|
|
|
namespace WINMLP {
|
|
|
|
struct LogicalProcessorInformation {
|
|
std::unique_ptr<char[]> Buffer;
|
|
size_t Length;
|
|
};
|
|
|
|
struct CoreCounter {
|
|
uint32_t PhysicalCores = 0;
|
|
uint32_t LLCCores = 0;
|
|
};
|
|
|
|
static LogicalProcessorInformation GetLogicalProcessorInfos(LOGICAL_PROCESSOR_RELATIONSHIP relationship) {
|
|
DWORD length = 0;
|
|
DWORD rc = GetLogicalProcessorInformationEx(relationship, nullptr, &length);
|
|
|
|
assert(rc == FALSE);
|
|
|
|
auto processorInformationBytes = std::make_unique<char[]>(length);
|
|
|
|
rc = GetLogicalProcessorInformationEx(
|
|
relationship, reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(processorInformationBytes.get()), &length
|
|
);
|
|
|
|
assert(rc == TRUE);
|
|
|
|
return {std::move(processorInformationBytes), length};
|
|
}
|
|
|
|
uint32_t CountSetBits(DWORD input) {
|
|
uint32_t c;
|
|
for (c = 0; input; c++) {
|
|
input &= input - 1;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
static CoreCounter GetCoreInfo() {
|
|
auto logicalProcessorInformation = GetLogicalProcessorInfos(RelationAll);
|
|
|
|
CoreCounter cores;
|
|
DWORD dwLevel2GroupMask = 0;
|
|
DWORD dwLevel3GroupMask = 0;
|
|
size_t read = 0;
|
|
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX currentProcessorInfo = NULL;
|
|
|
|
while ((read + FIELD_OFFSET(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, Processor)) < logicalProcessorInformation.Length
|
|
) {
|
|
currentProcessorInfo =
|
|
reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(logicalProcessorInformation.Buffer.get() + read);
|
|
if ((read + currentProcessorInfo->Size) > logicalProcessorInformation.Length) {
|
|
break;
|
|
}
|
|
|
|
switch (currentProcessorInfo->Relationship) {
|
|
case RelationProcessorCore:
|
|
cores.PhysicalCores++;
|
|
break;
|
|
case RelationCache:
|
|
//Cache level masks count Logicial processors
|
|
if (currentProcessorInfo->Cache.Level == 2) {
|
|
dwLevel2GroupMask |= currentProcessorInfo->Cache.GroupMask.Mask;
|
|
} else if (currentProcessorInfo->Cache.Level == 3) {
|
|
dwLevel3GroupMask |= currentProcessorInfo->Cache.GroupMask.Mask;
|
|
}
|
|
break;
|
|
}
|
|
|
|
read += currentProcessorInfo->Size;
|
|
}
|
|
|
|
cores.LLCCores = cores.PhysicalCores - CountSetBits(dwLevel2GroupMask & ~dwLevel3GroupMask);
|
|
|
|
return cores;
|
|
}
|
|
|
|
uint32_t HardwareCoreEnumerator::DefaultIntraOpNumThreads() {
|
|
// # of physical cores = # of P cores + # of E Cores + # of Soc Cores.
|
|
// # of logical cores = # of P cores x 2 (if hyper threading is enabled) + # of E cores + # of Soc Cores.
|
|
auto cores = GetCoreInfo();
|
|
|
|
#if !defined(_M_ARM64EC) && !defined(_M_ARM64) && !defined(__aarch64__)
|
|
const int kVendorID_Intel[3] = {0x756e6547, 0x6c65746e, 0x49656e69}; // "GenuntelineI"
|
|
int regs_leaf0[4];
|
|
int regs_leaf7[4];
|
|
__cpuid(regs_leaf0, 0);
|
|
__cpuid(regs_leaf7, 0x7);
|
|
|
|
auto isIntel = (kVendorID_Intel[0] == regs_leaf0[1]) && (kVendorID_Intel[1] == regs_leaf0[2]) &&
|
|
(kVendorID_Intel[2] == regs_leaf0[3]);
|
|
|
|
auto isHybrid = (regs_leaf7[3] & (1 << 15));
|
|
|
|
if (isIntel && isHybrid) {
|
|
// We want to use the number of physical cores, but exclude cores without an LLC
|
|
return cores.LLCCores;
|
|
}
|
|
#endif
|
|
|
|
return cores.PhysicalCores;
|
|
}
|
|
|
|
} // namespace WINMLP
|