Glossary · Computing
Shared memory
Also called multiprocessing.shared_memory, pipes, inter-process communication, IPC
A block of memory that several processes can read and write directly, so data passes between them without being copied.
A program that uses many processors usually runs as many separate processes. Each one has its own memory, and by default none can see another’s. To pass data between them, the usual way is a pipe: one process packs the data into bytes (serialising, or “pickling” in Python), writes them, and the other reads and unpacks them. That is simple and safe, but every byte is copied, and the packing and unpacking cost processor time.
With shared memory, the operating system maps one block of memory into several processes at once. One process writes an array into it, and the others read the same array where it lies, with no copying. The cost moves to coordination: a process must not read data while another is still writing it. A common pattern is double buffering: two copies of the block, one being filled while the other is read, swapped each round.
In Python, the standard library’s multiprocessing.shared_memory provides such blocks, and NumPy or PyTorch arrays can be laid directly on top of them.
In this project
Training runs many worker processes that simulate the fighter and a few learner processes that update the network. Until 20 October, each iteration sent the network’s weights (about 2 MB) down a pipe to each of 168 workers and sent 168 batches of experience back, and one core packed, unpacked and joined them. On a 192-vCPU machine that one core became the bottleneck. With the weights and the experience in double-buffered shared memory, training went from 44 to 50 M steps an hour, and to about 70 M with the other changes of that day (see Blocking).