I'm interested in theoretical limits, perhaps with examples of systems having huge numbers of CPU's.
At least 2048 in practice. As a concrete example, SGI sells its UV system, which can use 256 sockets (2,048 cores) and 16TB of shared memory, all running under a single kernel. I know that there are at least a few systems that have been sold in this configuration.
According to SGI:
Altix UV runs completely unmodified Linux, including standard distributions from both Novell and Red Hat.
this is what Launchpad has to say about Ubuntu, so I guess it applies to others:
1.Intel x86: Maximum CPUs: 32 (including logical CPUs) Maximum memory: 64GB Maximum filesize: 8TB Maximum filesystem size (ext3) 16TB Maximum per-process virtual address space: 4GB 2.AMD64/EM64T: Maximum CPUs: 64 Maximum memory: 128GB Maximum filesize: 8TB Maximum filesystem size (ext3): 16TB Maximum per-process virtual address space: N/A These are standard max limitations whereas Linux cluster systems can scale up to 1024 CPU's.
That is 32 or 64 CPUs for x86 and x86_64 respectively.
Redhat says the same, but in a management-friendly table. Redhat EL6 can do 32 for x86, or 128 or 4096 CPUs cores for x86_64.
The x86_64 Linux kernel can handle a maximum of 4096 Processor threads in a single system image. This means that with hyper threading enabled, the maximum number of processor cores is 2048. Yes there is computers with more than 2048 processor cores; but these runs as clusters where several Linux kernels cooperate, connected with a high speed interconnect, typically an Infiniband fabric.
from the most current kernel 3.13, in ~/arch/x86/Kconfig :
---help--- This allows you to specify the maximum number of CPUs which this kernel will support. If CPUMASK_OFFSTACK is enabled, the maximum supported value is 4096, otherwise the maximum value is 512. The minimum value which makes sense is 2. This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image.
This baby runs 10,368!
Threads are subjective to the multitasking model and thread management scheme. The Gdt of intel based systems is used in linux if I remember rightly. The idea is it has a possibility 8192 threads at max size. This assuming that the system is using the gdt to manage the threads. On 32 bit machines task switching is managed and the on 32 and 64 bit machines interrupt vectors need to have gdt entries. Not sure how arm does it but the same articulation has to be achieved. Task switching concepts iterate the GDT in tasking models.
If you break out of the gdt scheme you assumably can reach what you have memory for when you have, for each thread, a page stack frame, page code base for the thread and page of heap space. You cannot assume you have a page of code or heap, which is the random variables. Generally there are two stack frames for each thread, one maintained by the thread and one maintained by the linux kernel. You add virtual memory concepts of swap space and the model gets blown out of the water but it is about thread priority..