A method to assign a thread to a particular core in a multi-core processor, wherein the multi-core processor includes a first core, a second core, a first memory controller, and a second memory controller, the method comprising: determining that the thread is bandwidth-bound or latency-bound based on cache misses per second being greater than a second threshold value or being greater than a first threshold value and less than the second threshold value, respectively; in response to determining that the thread is bandwidth-bound, determining one or more cores (220, 240) at an equal distance between the first memory controller and the second memory controller; assigning the thread to the one or more cores (220, 240); in response to determining that the thread is latency-bound: determining first miss data that relates to a first number of times the first memory controller fetches from a memory in response to cache misses experienced by the first core within a time period; determining second miss data that relates to a second number of times the first memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; determining third miss data that relates to a third number of times the second memory controller fetches from the memory in response to cache misses experienced by the first core within the same time period; determining fourth miss data that relates to a fourth number of times the second memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; and assigning the thread to the first core or to the second core based on costs to communicate between the cores (220, 240) and the memory controllers (181, 183), wherein the costs are based on evaluating the first, second, third and fourth miss data and on data in a proximity table, wherein the proximity table shows how many hops are between the cores (220, 240) and the memory controllers (181, 183). determining that the thread is bandwidth-bound or latency-bound based on cache misses per second being greater than a second threshold value or being greater than a first threshold value and less than the second threshold value, respectively; in response to determining that the thread is bandwidth-bound, determining one or more cores (220, 240) at an equal distance between the first memory controller and the second memory controller; assigning the thread to the one or more cores (220, 240); in response to determining that the thread is latency-bound: determining first miss data that relates to a first number of times the first memory controller fetches from a memory in response to cache misses experienced by the first core within a time period; determining second miss data that relates to a second number of times the first memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; determining third miss data that relates to a third number of times the second memory controller fetches from the memory in response to cache misses experienced by the first core within the same time period; determining fourth miss data that relates to a fourth number of times the second memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; and assigning the thread to the first core or to the second core based on costs to communicate between the cores (220, 240) and the memory controllers (181, 183), wherein the costs are based on evaluating the first, second, third and fourth miss data and on data in a proximity table, wherein the proximity table shows how many hops are between the cores (220, 240) and the memory controllers (181, 183). determining first miss data that relates to a first number of times the first memory controller fetches from a memory in response to cache misses experienced by the first core within a time period; determining second miss data that relates to a second number of times the first memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; determining third miss data that relates to a third number of times the second memory controller fetches from the memory in response to cache misses experienced by the first core within the same time period; determining fourth miss data that relates to a fourth number of times the second memory controller fetches from the memory in response to cache misses experienced by the second core within the same time period; and assigning the thread to the first core or to the second core based on costs to communicate between the cores (220, 240) and the memory controllers (181, 183), wherein the costs are based on evaluating the first, second, third and fourth miss data and on data in a proximity table, wherein the proximity table shows how many hops are between the cores (220, 240) and the memory controllers (181, 183).