Let me add my $0.02. CPUs seem to hide memory issues with more-and-more cache. The most recent AMD EPYC chips have 256MB of L3 cache. Intel has less L3 cache, but has something like 1MB of L2 cache per core now (!!!). AMD has shown us the future: 64MB SRAM being grafted onto these chips to maybe add +64MB per die (or maybe 768 MB of L3 cache in a hypothetical EPYC in the future).
GPUs have a different design. GPUs have almost no caches worth discussing. Instead, GPUs have manually managed scratch RAM, also known as __shared__ memory (which roughly fits in the L1 cache speeds). __shared__ is pretty small though, maybe only 64kB or so. The real important thing about __shared__ is that any SIMD lane can read/write to it at high speeds, so it serves as a good area for inter-thread communications. ("Thread" is a bit ambiguous, but... lets just simplify it and call them cuda-threads).
The other bit GPUs have are a ridiculous number of registers. AMD RDNA has 1024-registers, of which up to 256 can be allocated into a kernel. (The device driver of modern GPUs will further parallelize loads by requesting only some of the registers per invocation. A well written memcpy kernel may only need 64 vector-registers for example... the device driver may load 16 parallel instances of this hypothetical kernel to run in parallel on the GPU core so all 1024 registers are used).
These 1024-registers are 32-bits and 32-SIMD-lanes wide on AMD RDNA, or 128kB of registers per WGP (workgroup processor, an AMD RDNA "core"). I kid you not: AMD RDNA has more registers per WGP than Intel Skylake had L1 cache per core!!
---------------
As such, we can immediately see how modern GPUs and CPUs get around the memory bandwidth issue. CPUs try to hide it with increasingly large caches... while GPU register sizes are so large that it borders on insanity.