  Graphics Processing Units (GPUs) consisting of Streaming Multiprocessors
(SMs) achieve high throughput by running a large number of threads and context
switching among them to hide execution latencies. The number of thread blocks,
and hence the number of threads that can be launched on an SM, depends on the
resource usage--e.g. number of registers, amount of shared memory--of the
thread blocks. Since the allocation of threads to an SM is at the thread block
granularity, some of the resources may not be used up completely and hence will
be wasted.
  We propose an approach that shares the resources of SM to utilize the wasted
resources by launching more thread blocks. We show the effectiveness of our
approach for two resources: register sharing, and scratchpad (shared memory)
sharing. We further propose optimizations to hide long execution latencies,
thus reducing the number of stall cycles. We implemented our approach in
GPGPU-Sim simulator and experimentally validated it on several applications
from 4 different benchmark suites: GPGPU-Sim, Rodinia, CUDA-SDK, and Parboil.
We observed that with register sharing, applications show maximum improvement
of 24%, and average improvement of 11%. With scratchpad sharing, we observed a
maximum improvement of 30% and an average improvement of 12.5%.
