FGenericPlatformMisc::NumberOfCoresIncludingHyperthreads is not detecting hyperthreads

FGenericPlatformMisc::NumberOfCoresIncludingHyperthreads is detecting my core count but it seems to be ignoring my hyperthreads. Including hyperthreads, my system has a total of 8 logical cores but the function only returns 4. My processor is Intel(R) Core™ i7-2600k CPU @ 3.40GHz.
I’m also running 64 bit Windows 7 and compiling my project at 64 bit.

EDIT::

The issue is actually with the implementation of the function. The current implementation at lines 769-772 of GenericPlatformMisc.cpp is:

int32 FGenericPlatformMisc::NumberOfCoresIncludingHyperthreads()
{
	return FPlatformMisc::NumberOfCores();
}

And I believe it should be:

int32 FGenericPlatformMisc::NumberOfCoresIncludingHyperthreads()
{
	return FPlatformMisc::NumberOfCoresIncludingHyperthreads();
}

I just looked at the 4.9 branch on github and it’s wrong in that version as well.

i’m lack knowledges on core optimisation, but guess, it’s WinAPI GetLogicalProcessorInformation function (sysinfoapi.h) - Win32 apps | Microsoft Learn GetLogicalProcessorInformation

int32 FWindowsPlatformMisc::NumberOfCores()
{
static int32 CoreCount = 0;
if (CoreCount == 0)
{
if (FParse::Param(FCommandLine::Get(), TEXT(“usehyperthreading”)))
{
CoreCount = NumberOfCoresIncludingHyperthreads();
}
else
{
// Get only physical cores
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION InfoBuffer = NULL;
::DWORD BufferSize = 0;

         // Get the size of the buffer to hold processor information.
         ::BOOL Result = GetLogicalProcessorInformation(InfoBuffer, &BufferSize);
         check(!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
         check(BufferSize > 0);

         // Allocate the buffer to hold the processor info.
         InfoBuffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)FMemory::Malloc(BufferSize);
         check(InfoBuffer);

         // Get the actual information.
         Result = GetLogicalProcessorInformation(InfoBuffer, &BufferSize);
         check(Result);

         // Count physical cores
         const int32 InfoCount = (int32)(BufferSize / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
         for (int32 Index = 0; Index < InfoCount; ++Index)
         {
             SYSTEM_LOGICAL_PROCESSOR_INFORMATION* Info = &InfoBuffer[Index];
             if (Info->Relationship ==  RelationProcessorCore)
             {
                 CoreCount++;
             }
         }
         FMemory::Free(InfoBuffer);
     }
 }
 return CoreCount;

}

i don’t sure code sample from WinAPI will give you different result, the only way check it - experiment, so compile it and see if result same or not, if result same, then maybe you misunderstood something in difinitions of logical/physical cores and what actually matter or can be used, also you have to note that maybe there’s no need to manually drive cores, because OS have own optimisation and split CPU load on cores, the only thing you need to do is allow multythreading so separate threads can be executed on other cores, the only way achieve it i know is FTickFunction and it’s property bRunOnAnyThread FTickFunction | Unreal Engine Documentation but have no example of use

wikipedia (at least russian) tells Hyper-threading must be enabled in order to let windows detect 1 physical core as 2 logical, but again i think you don’t need manually drive cores, the only thing you have to care about - make your UE4 game multythreading, by default all blueprints are single threaded, it mean in case you have 2 actors with tick event physically it will be executed in 1 thread and mean it will be executed one after another, to make it working together try find how use FTickFunction and it’s property bRunOnAnyThread FTickFunction | Unreal Engine Documentation

I made an edit to the post that includes my findings.

i saw, so what’s for you want know count of physical/logical cores?

The end goal is to get the total number of logical cores minus 1 so I can spawn threads to handle some manual loading and unloading of data. My game is mostly procedurally or user generated content. In order to generate/load the world efficiently, it needs to run on as many threads as possible. But too many threads would be a waste of resources.

That might not be a bug, but intended because the generic layer might make assumptions that hyper threads don’t exist :wink: As I stated in the other thread, you should always use the typedef-ed FPlatform* version so that least common denominator code doesn’t break on different platforms. I’ll ask the platform team to look at whether it’s an intentional bug (by design) or an unintended one

you should also know limits of multy-thread implementation, as Rama stated A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums

What Not to Do

Do not try to modify, create, or delete UObjects from other threads!
You can prepare all the data / do all the calculations, but only the game thread should be actually spawning / modifying / deleting UObjects / AActors.

Dont try to use TimerManager outside of the game thread :slight_smile:
Don’t try to draw debug lines/points etc, as it will likely crash, ie DrawDebugLine(etc…)