A method comprising: generating, by a processing unit, batches of memory requests, wherein each batch of memory requests respectively originates from execution of a respective group of threads; tagging, by the processing unit, a first batch of memory requests of the batches of memory requests with first metadata, wherein the first metadata includes data identifying a group of threads from which the first batch of memory requests originates, wherein the group of threads from which the first batch of memory requests originates is a first group of threads; tagging, by the processing unit, a second batch of memory requests of the batches of memory requests with second metadata, wherein the second metadata includes data identifying a group of threads from which the second batch of memory requests originates, wherein the group of threads from which the second batch of memory requests originates is the first group of threads; storing, before sending any memory request of the first batch of memory requests to a first memory or a memory controller, the first batch of memory requests and the first metadata in a conflict arbitration queue; storing, before sending any memory request of the second batch of memory requests to the first memory or the memory controller, the second batch of memory requests and the second metadata in the conflict arbitration queue; and performing, using the first metadata and the second metadata, conflict arbitration between only the first batch of memory of requests and the second batch of memory requests stored in the conflict arbitration queue, wherein at least one other batch of memory requests stored in the conflict arbitration queue originates from at least one group of threads different from the first group of threads. generating, by a processing unit, batches of memory requests, wherein each batch of memory requests respectively originates from execution of a respective group of threads; tagging, by the processing unit, a first batch of memory requests of the batches of memory requests with first metadata, wherein the first metadata includes data identifying a group of threads from which the first batch of memory requests originates, wherein the group of threads from which the first batch of memory requests originates is a first group of threads; tagging, by the processing unit, a second batch of memory requests of the batches of memory requests with second metadata, wherein the second metadata includes data identifying a group of threads from which the second batch of memory requests originates, wherein the group of threads from which the second batch of memory requests originates is the first group of threads; storing, before sending any memory request of the first batch of memory requests to a first memory or a memory controller, the first batch of memory requests and the first metadata in a conflict arbitration queue; storing, before sending any memory request of the second batch of memory requests to the first memory or the memory controller, the second batch of memory requests and the second metadata in the conflict arbitration queue; and performing, using the first metadata and the second metadata, conflict arbitration between only the first batch of memory of requests and the second batch of memory requests stored in the conflict arbitration queue, wherein at least one other batch of memory requests stored in the conflict arbitration queue originates from at least one group of threads different from the first group of threads.