# CUDA-Optimized GPU Acceleration of 3 GPP 3D Channel Model Simulations for 5G Network Planning
## 4 GPU-Based Acceleration Using NVIDIA CUDA  
GPUs are a type of single-instruction-multiple-data (SIMD) architecture where the same instruction is executed repeatedly on different data in parallel. GPUs are specifically designed to run thousands of threads in parallel for higher throughput and use multi-threading to hide memory latency. Efficient management of GPU resources can be achieved through high-level programming languages based on the underlying computing architectures, resulting in improved performance.  
Popular parallel computing architectures in the industry include the Open Computing Language (OpenCL) [26], Open Multi-Processing (OpenMP), and CUDA [27], a parallel programming language for managing computations on NVIDIA GPUs. Several code optimization techniques, both generic to GPU code and specific to CUDA, are required to efficiently utilize the on-chip resources and increase the overall performance.  
\begin{table}
\begin{tabular}{l r l r} \hline \hline
**Parameter** & **Value** & **Parameter** & **Value** \\ \hline Polarizations & 2 & Oversampling factor & 1 to 4 \\ Elements on H-Planes & 4 & Elements on V-Planes & 1 to 4 \\ Carrier Frequency (MHz) & 3600 & Sampling freq. (Hz) & 122.88 \\ Transmitting Antennas & 2 to 32 & Receiving Antennas & 2 to 32 \\ Clusters & 23 (CDL-B) \& 13 (CDL-D) & Rays & 20 \\ User Speed (km/h) & 120 & Subcarriers & 2048 \\ \hline \hline \end{tabular}
\end{table}
Table 1: Summary of channel model emulator parameters.  
CUDA-based acceleration code consists of two components: the _host code_, which runs on the general-purpose CPU and is responsible for memory and device management and a collection of functions called the _kernel code_, which runs on the GPU accelerator device.  
Threads in CUDA are the units of computation and are modeled as functions in the kernel code. _They are completely concurrent unless synchronized by the hardware or by the designer._ In order to efficiently map threads to the architecture of the GPU, they are arranged in 3D clusters called _blocks_. These clusters are then combined into a 3D grid. The CUDA programming model groups a set of 32 threads into a single entity known as a _warp_. Concurrent threads (1) within a warp are automatically synchronized in lockstep by the hardware, whereas (2) threads within a block can be synchronized via _barriers_ by the designer, e.g., to enable all threads to complete data transfers before starting a computation on those data, and (3) thread blocks cannot be synchronized with each other at all.  
When a designer has to port an application that was originally written for a CPU to a GPU, the code must be completely restructured to _explicitly expose parallel computations and optimize memory accesses_, as the implicit optimizations provided by compilers are usually insufficient.  
GPU architecture for acceleration and CUDA programming model prospective of GPU are shown in Figure 2.  
The main characteristics of the GPU programming languages, and of CUDA in particular, are discussed below:  
1. Allocating arrays to explicit levels in the memory hierarchy.
2. Explicitly modeling concurrency via threads.