1. A method of non-intrusively measuring a memory profile of a thread under test, the method comprising: executing a detection thread in parallel with the thread under test, the thread under test executed on a first core of a multi-core processor and the detection thread executed on a second core of the multi-core processor; generating a pattern of cache miss memory reads on the detection thread in order to access a memory shared by the first core and the second core; periodically obtaining read times in the detection thread indicating the amount of time taken to complete the cache miss memory reads generated on the detection thread; determining the memory profile of the thread under test based on the obtained read times of the detection thread; obtaining at least a second memory profile from at least a second thread; and with the memory profiles of the thread under test and the at least a second thread, determining how any two threads can be paired based on their memory access profiles; wherein pairing of the any two threads, comprises one of: pairing a memory intensive thread with another memory intensive thread, both having non-overlapping memory access profiles; pairing a memory intensive thread with a computational intensive thread; and pairing a memory intensive thread with an input/output intensive thread.