Skip to content

Commit

Permalink
Merge pull request #7635 from FirebirdSQL/work/gh_7634
Browse files Browse the repository at this point in the history
Improvement #7634 : Include Performance Cores only in default affinity mask
  • Loading branch information
hvlad authored Jun 17, 2023
2 parents a6d0fc1 + 84a70c8 commit 19564b3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
6 changes: 6 additions & 0 deletions builds/install/misc/firebird.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,12 @@
# CPU 1 and CPU 2, the value is 3. To use CPU 2 and CPU 3, the value
# is 6. The default value is 0 - no affinity will be set.
#
# About systems with heterogeneous (Efficient\Performance) set of cores:
# on Windows 10 and later, if affinity is not set nor by CpuAffinityMask,
# nor by the caller process, then server tries to exclude efficient cores
# from own affinity mask. I.e. default affinity mask includes performance
# cores only.
#
# Type: integer
#
#CpuAffinityMask = 0
Expand Down
4 changes: 4 additions & 0 deletions src/common/os/os_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ namespace os_utils

#endif // WIN_NT

#ifdef WIN_NT
void setDefaultAffinity();
#endif

class CtrlCHandler
{
public:
Expand Down
60 changes: 60 additions & 0 deletions src/common/os/win32/os_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include "../common/classes/array.h"
#include "../common/classes/init.h"
#include "../common/classes/GenericMap.h"
#include "../common/gdsassert.h"
#include "../common/os/guid.h"
#include "../common/os/os_utils.h"
Expand Down Expand Up @@ -560,6 +561,65 @@ void getUniqueFileId(HANDLE fd, UCharBuffer& id)
sizeof(file_info.nFileIndexLow));
}

void setDefaultAffinity()
{
HANDLE hCurrProc = GetCurrentProcess();

DWORD_PTR procMask, sysMask, newMask;
GetProcessAffinityMask(hCurrProc, &procMask, &sysMask);

// Don't change affinity if it was set by caller process
if (procMask != sysMask)
return;

newMask = sysMask;

DWORD len = 0;

if (!GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &len))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return;
}

HalfStaticArray<UCHAR, 1024, SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX> buff;
auto p = buff.getBuffer(len);
auto const end = p + len;
auto pSLPI = reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(p);

if (!GetLogicalProcessorInformationEx(RelationProcessorCore, pSLPI, &len))
return;

// Efficiency Class to Cores map
GenericMap<NonPooledPair<int, DWORD_PTR>> effClassMasks;

while (p < end)
{
if (pSLPI->Relationship == RelationProcessorCore)
{
DWORD_PTR coreMask = 0;
for (size_t i = 0; i < pSLPI->Processor.GroupCount; i++)
coreMask |= pSLPI->Processor.GroupMask[i].Mask;

DWORD_PTR* pMask = effClassMasks.get(pSLPI->Processor.EfficiencyClass);
if (!pMask)
effClassMasks.put(pSLPI->Processor.EfficiencyClass, coreMask);
else
*pMask |= coreMask;
}

p += pSLPI->Size;
pSLPI = reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(p);
}

// Exclude efficient cores, i.e. cores with lowest efficient class
if (effClassMasks.count() > 1)
newMask &= ~(*effClassMasks.begin()).second;

if (newMask && newMask != procMask)
SetProcessAffinityMask(hCurrProc, newMask);
}


/// class CtrlCHandler

Expand Down
2 changes: 2 additions & 0 deletions src/remote/server/os/win32/srvr_w32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE /*hPrevInst*/, LPSTR lpszArgs,
const DWORD_PTR affinity = Config::getCpuAffinityMask();
if (affinity)
SetProcessAffinityMask(GetCurrentProcess(), affinity);
else
os_utils::setDefaultAffinity();

protocol_inet[0] = 0;

Expand Down

0 comments on commit 19564b3

Please sign in to comment.