1. An apparatus comprising: a plurality of processing nodes, each processing node including a plurality of processing units and a main memory serving as local memory for the plurality of processing units of each respective processing node; a bus connected to the plurality of processing nodes, the bus configured to connect the plurality of processing units of each processing node to a different main memory of a different processing node as shared memory, wherein access to local memory has a first memory access latency and access to shared memory has a second memory access latency, and the first memory access latency is less than the second memory access latency, and wherein the plurality of processing nodes are configured to: execute a plurality of threads that are distributed across the plurality of processing nodes, detect, for each one of the plurality of threads, a number of memory accesses made from each one of the plurality of processing nodes by sampling memory accesses made from each one of the plurality of processing nodes, determine a plurality of locality values, by determining, for each one of the plurality of threads, locality values which are representative of a fraction of memory accesses made from each of the plurality of processing nodes, determine a plurality of processing time values, by determining, for each one of the plurality of threads, a processing time value for a sampling period, determine a plurality of weighted locality values, by multiplying, for each one of the plurality of threads, each respective locality value by each respective processing time value, and determine a memory distribution across the plurality of processing nodes based on the plurality of weighted locality values.