All modern CPUs have memory controllers built in as opposed to using a distinct "northbridge" chip. The RAM attaches directly to the CPU socket (or soldered BGA). In multi-socket systems, this means there are memory buses coming off each CPU, and for one CPU to reach memory attached to the other CPU, it needs to go through that CPU via the interconnect. Here's some ASCII art of a system with 3 memory channels from each CPU (old Mac Pro):
+------+ +------+
| CPU0 +==interconnect==+ CPU1 |
+-+-+-++ ++-+-+-+
| \ \ / / |
MEM0 | \ / | MEM5
MEM1 MEM2 MEM3 MEM4
Going via the interconnect introduces extra latency and consumes its bandwidth. Therefore, it's more efficient to pin threads and/or processes to specific CPU sockets, and to allocate memory for it from that socket's associated physical memory. This requires kernel support, and for absolute top performance you also want a user space API, so you don't need to rely on the in-kernel heuristics.
Lacking software support means you have to fall back to whatever the hardware does automatically. Current multi-socket x86 CPUs all offer an "interlaced" mode for this (sort of like RAID0), where they dispatch to physical socket based on some physical address bits, e.g.:
0x00000000-0x0000003f: CPU0's RAM
0x00000040-0x0000007f: CPU1's RAM
0x00000080-0x000000bf: CPU0's RAM
0x000000c0-0x000000ff: CPU1's RAM
and so on. This spreads the extra latency evenly. Makes for consistent but poor memory performance. The mode is selected during system initialisation, i.e. is the responsibility of the Firmware (BIOS/EFI). Non-Apple workstations and servers typically let you select this as part of the pre-boot system setup UI.
It depends on the motherboard layout, but you'll find that there are groups of DIMM slots located near each CPU socket in multi-socket systems. Physical proximity helps keep speeds high.