mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-26 14:01:02 +00:00
only run the main thread on P-cores
This commit is contained in:
parent
9e19d22d46
commit
a202404d16
3 changed files with 115 additions and 2 deletions
|
@ -63,6 +63,8 @@ add: /waitms <milliseconds> to delay command executions by the specified number
|
|||
add: r_alphaToCoverageMipBoost <0.0 to 0.5> (default: 0.125) boosts the alpha value of higher mip levels
|
||||
with A2C enabled, it prevents alpha-tested surfaces from fading (too much) in the distance
|
||||
|
||||
chg: with hybrid core CPUs (e.g. Intel gen 12+) on Windows, the main thread will only run on the P-cores
|
||||
|
||||
chg: the client can now read .wav files from the local file system when connected to a pure server
|
||||
this allows e.g. cg_fragSound to load sounds from the local file system instead of .pk3 files
|
||||
|
||||
|
|
|
@ -871,6 +871,116 @@ static void WIN_RegisterDemoShellCommands()
|
|||
}
|
||||
|
||||
|
||||
static void WIN_SetCorePreference()
|
||||
{
|
||||
struct local_resources_t {
|
||||
~local_resources_t()
|
||||
{
|
||||
if ( cpuSetBuffer != NULL ) {
|
||||
free( cpuSetBuffer );
|
||||
}
|
||||
if ( pcoreIdBuffer != NULL ) {
|
||||
free( pcoreIdBuffer );
|
||||
}
|
||||
if ( library != NULL ) {
|
||||
FreeLibrary( library );
|
||||
}
|
||||
}
|
||||
|
||||
byte* cpuSetBuffer = NULL;
|
||||
ULONG* pcoreIdBuffer = NULL;
|
||||
HMODULE library = NULL;
|
||||
};
|
||||
|
||||
local_resources_t res;
|
||||
|
||||
res.library = LoadLibraryA( "kernel32.dll" );
|
||||
if ( res.library == NULL ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: Failed to open kernel32.dll\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
typedef BOOL (WINAPI* GetSystemCpuSetInformationFPtr)( PSYSTEM_CPU_SET_INFORMATION Information, ULONG BufferLength, PULONG ReturnedLength, HANDLE Process, ULONG Flags );
|
||||
typedef BOOL (WINAPI* SetThreadSelectedCpuSetsFPtr)( HANDLE Thread, const ULONG* CpuSetIds, ULONG CpuSetIdCount );
|
||||
const GetSystemCpuSetInformationFPtr pGetSystemCpuSetInformation = (GetSystemCpuSetInformationFPtr)GetProcAddress( res.library, "GetSystemCpuSetInformation" );
|
||||
const SetThreadSelectedCpuSetsFPtr pSetThreadSelectedCpuSets = (SetThreadSelectedCpuSetsFPtr)GetProcAddress( res.library, "SetThreadSelectedCpuSets" );
|
||||
if ( pGetSystemCpuSetInformation == NULL || pSetThreadSelectedCpuSets == NULL ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: Failed to grab function pointers\n" );
|
||||
Com_Printf( "^3WIN_SetCorePreference: Ignore this if you're not on Windows 10/11\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG requiredByteCount = 0;
|
||||
if ( pGetSystemCpuSetInformation( NULL, 0, &requiredByteCount, GetCurrentProcess(), 0 ) != TRUE &&
|
||||
GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: GetSystemCpuSetInformation failed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
res.cpuSetBuffer = (byte*)malloc( requiredByteCount );
|
||||
if ( res.cpuSetBuffer == NULL ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: malloc failed with %s\n", Com_FormatBytes( (int)requiredByteCount ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pGetSystemCpuSetInformation( (SYSTEM_CPU_SET_INFORMATION*)res.cpuSetBuffer, requiredByteCount, &requiredByteCount, GetCurrentProcess(), 0 ) != TRUE ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: GetSystemCpuSetInformation failed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG pcoreCount = 0;
|
||||
ULONG ecoreCount = 0;
|
||||
byte* cpuSetByte = res.cpuSetBuffer;
|
||||
for ( ULONG cpuSetByteOffset = 0; cpuSetByteOffset < requiredByteCount; ) {
|
||||
SYSTEM_CPU_SET_INFORMATION* cpuSet = (SYSTEM_CPU_SET_INFORMATION*)cpuSetByte;
|
||||
if ( cpuSet->Type == CpuSetInformation ) {
|
||||
if ( cpuSet->CpuSet.EfficiencyClass > 0 ) {
|
||||
pcoreCount++;
|
||||
} else {
|
||||
ecoreCount++;
|
||||
}
|
||||
}
|
||||
cpuSetByte += cpuSet->Size;
|
||||
cpuSetByteOffset += cpuSet->Size;
|
||||
}
|
||||
if ( pcoreCount + ecoreCount <= 1 ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: no valid CPU core information found\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t pcoreIdBufferSize = (size_t)pcoreCount * sizeof(ULONG);
|
||||
res.pcoreIdBuffer = (ULONG*)malloc( pcoreIdBufferSize );
|
||||
if ( res.pcoreIdBuffer == NULL ) {
|
||||
Com_Printf( "^3WIN_SetCorePreference: malloc failed with %s\n", Com_FormatBytes( (int)pcoreIdBufferSize ) );
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG* currPCoreId = res.pcoreIdBuffer;
|
||||
cpuSetByte = res.cpuSetBuffer;
|
||||
for ( ULONG cpuSetByteOffset = 0; cpuSetByteOffset < requiredByteCount; ) {
|
||||
SYSTEM_CPU_SET_INFORMATION* cpuSet = (SYSTEM_CPU_SET_INFORMATION*)cpuSetByte;
|
||||
if ( cpuSet->Type == CpuSetInformation ) {
|
||||
if ( cpuSet->CpuSet.EfficiencyClass > 0 ) {
|
||||
*currPCoreId++ = (ULONG)cpuSet->CpuSet.Id;
|
||||
}
|
||||
}
|
||||
cpuSetByte += cpuSet->Size;
|
||||
cpuSetByteOffset += cpuSet->Size;
|
||||
}
|
||||
|
||||
if ( pcoreCount > 0 && ecoreCount > 0 ) {
|
||||
Com_Printf( "CPU configuration: %dP/%dE hybrid cores\n", (int)pcoreCount, (int)ecoreCount );
|
||||
if ( pSetThreadSelectedCpuSets( GetCurrentThread(), res.pcoreIdBuffer, pcoreCount) ) {
|
||||
Com_Printf( "Main thread successfully set to run on P-Cores only\n" );
|
||||
} else {
|
||||
Com_Printf( "^3WIN_SetCorePreference: SetThreadSelectedCpuSets failed\n" );
|
||||
}
|
||||
} else {
|
||||
Com_Printf( "CPU configuration: %d homogeneous cores\n", (int)(pcoreCount + ecoreCount) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -911,6 +1021,7 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
WIN_RegisterExceptionCommands();
|
||||
WIN_RegisterMonitorCommands();
|
||||
WIN_RegisterDemoShellCommands();
|
||||
WIN_SetCorePreference();
|
||||
|
||||
NET_Init();
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#if defined(_WIN32_WINNT)
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define WINVER _WIN32_WINNT_VISTA
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#define WINVER _WIN32_WINNT_WIN10
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WIN10
|
||||
|
||||
#if defined(UNICODE)
|
||||
#undef UNICODE
|
||||
|
|
Loading…
Reference in a new issue