FirebirdSQL / firebird

Firebird server, client and tools
https://www.firebirdsql.org/
1.26k stars 216 forks source link

Firebird 3.0.10 is only using 32 logical processors #7292

Open freddyertl opened 2 years ago

freddyertl commented 2 years ago

We recently moved to a new hardware running Windows Server 2012R2 with dual AMD Epyc with a total of 192 logical processors (2 sockets 48 cores 2 for HT). It seems that FB is only using 32 of them, if the data shown by Task Manager is correct. How to make use of all available processors/cores?

hvlad commented 2 years ago

Firebird uses single thread when run particular query. There is no special limitation in code to limit number of used CPU's. Thus, if you see 32 CPU's loaded it means there is no more than 32 simultaneous queries running at time.

EPluribusUnum commented 2 years ago

CpuAffinityMask in firebird.conf?

freddyertl commented 2 years ago

I haven't changed CpuAffinityMask because I read somewhere that by default FB uses all CPUs. I have 5 application servers with a connection pool size of 50 each. I ran a stress test with many requests translating into many statements, but it never shows more than 32 CPUs under load. I read about limitations in Windows and a workaround with processor groups. And that a process is assigned a primary group which limits the number of available CPUs unless a process is aware of this and is using the appropriate functions.

hvlad commented 2 years ago

Are your stress-tests CPU-bound ? Do you see 100% load of each of 32 CPU's ?

I read about limitations in Windows and a workaround with processor groups. And that a process is assigned a primary group which limits the number of available CPUs unless a process is aware of this and is using the appropriate functions.

Could you be a bit more specific here ?

freddyertl commented 2 years ago

I run jmeter to send HTTP requests to a HAProxy server which distributes the load across 5 Tomcat servers which then call Firebird. It's not completely producing 100% load all the time on each CPU, but you can clearly see that it's not using all CPUs. It seems Windows Server versions before 2022 use the concept of processor groups to work around a limitation to 64 logical processors. You can read about this here: https://docs.microsoft.com/en-us/windows/win32/procthread/processor-groups

EPluribusUnum commented 2 years ago

Switch to classic server. Each connection has it's application, so no CPU/app limit. BTW, does your connection pool is big enough?

freddyertl commented 2 years ago

I know that SuperClassic could also be used, but the question is, can I use SuperServer and still utilizing all cores? I think for a database server running exclusively on modern hardware with many cores it should be an obvious requirement.

hvlad commented 2 years ago

Could you explore CPU topology on your host ? How many processor groups exists and how many logical CPUs per group ?

freddyertl commented 2 years ago

There are 3 processor groups with 64 CPUs each. Firebird is assigned to processor group 1 which is different from the other groups because it has two nodes 2 and 3 with 32 CPUs each. The other groups consist of 1 node with 64 CPUs. It looks like Firebird is only using node 3 with its 32 CPUs even though all 64 CPUs are selected. And what is with the other processor groups? Can the be used by Firebird?

PG0 PG1 PG2

hvlad commented 2 years ago

As I already said Firebird does nothing special in this regards. Could you change affinity to make Firebird run on group with 64 CPU's ?

OS is responsible for scheduling processes and for creating NUMA nodes, processor groups, etc. There was message about settings in BIOS that changes of how Windows distribute CPUS per NUMA nodes. IIRC, it was about some HP machine with HP BIOS.

freddyertl commented 2 years ago

Let me try changing this to a group with just a single node. What do you think happens if I assign Firebird to more than one group?

hvlad commented 2 years ago

Firebird will work correctly, if you worry about it.

freddyertl commented 2 years ago

After reading a little bit more, I don't think setting it manually makes sense. Look at this information about processor groups from Microsoft:

By default, an application is constrained to a single group, which should provide ample processing capability for the typical application. The operating system initially assigns each process to a single group in a round-robin manner across the groups in the system.

With every restart this would most likely change the group again. I think this needs to be handled by Firebird:

An application that requires the use of multiple groups so that it can run on more than 64 processors must explicitly determine where to run its threads and is responsible for setting the threads' processor affinities to the desired groups.

hvlad commented 2 years ago

After reading a little bit more, I don't think setting it manually makes sense

The idea was to

I think this needs to be handled by Firebird:

I can think about such change but I have no way to test it, unfortunately.

EPluribusUnum commented 2 years ago

Also HyperThread could hurt performance because of the shared cache. https://web.archive.org/web/20120229063705/http://blogs.msdn.com/b/slavao/archive/2005/11/12/492119.aspx

livius2 commented 2 years ago

@hvlad

I can think about such change but I have no way to test it, unfortunately.

You can change code and test if it do not affect badly "normal" system. If it is ok, @freddyertl can test it self on his system with more CPU cores.