## 3 GPS SDR Design for CRPA Using General-Purpose Parallel Processors
### GPU-Based Parallel Correlator  
The basic design idea of the GPS SDR for CRPA is to maximize parallelism in receiver architecture. As discussed in Section 2, the carrier and code wipeoff has the biggest computational load (1,080\(N\) multiplications and additions every millisecond, in other words 1,080\(N\)/1,504\(N\)\(\approx\) 72% of total computational load, \(N\) = 20,000 in our case) but it can be highly parallelized. Compute Unified Device Architecture (CUDA) is NVIDIA's parallel computing architecture, and we use a CUDA-enabled GPU to perform the carrier and code wipeoff operations. Figure 5 illustrates our GPU-based parallel correlator. Our GPU code is written in CUDA C programming language [36,41]. Figure 4: Hardware setup for GPS SDR for four-element CRPA processing. The GTX 480 GPU used in this work has 15 multiprocessors and 480 CUDA cores (Table 1). Since each multiprocessor of GPUs of compute capability 2.x can have 1,536 active threads (Table 3), the GTX 480 GPU can have 1,536 \(\times\) 15 = 23,040 active threads. However, this maximum possible GPU occupancy may not be achieved for various reasons. The GPU occupancy is determined by the number of threads per thread block, the number of registers used \begin{table}
\begin{tabular}{|l|c|c|c|} \cline{2-4} \multicolumn{1}{c|}{} & \multicolumn{4}{c|}{Compute Capability} \\ \cline{2-4} \multicolumn{1}{c|}{} & 1.0 & 1.1 & 1.2 & 1.3 & 2.x \\ \hline Maximum number of resident thread blocks per multiprocessor & \multicolumn{4}{c|}{8} \\ \hline Maximum number of resident warps per multiprocessor & 24 & 32 & 48 \\ \hline Maximum number of resident threads per multiprocessor & 768 & 1024 & 1536 \\ \hline Number of 32-bit registers per multiprocessor & 8 K & 16 K & 32 K \\ \hline Maximum amount of shared memory per multiprocessor & \multicolumn{4}{c|}{16 KB} & 48 KB \\ \hline Number of shared memory banks & \multicolumn{4}{c|}{16} & 32 \\ \hline Amount of local memory per thread & \multicolumn{4}{c|}{16 KB} & 512 KB \\ \hline Maximum number of threads per block & \multicolumn{4}{c|}{512} & 1024 \\ \hline Atomic addition operating on 32-bit floating point values in & \multicolumn{4}{c|}{No} & Yes \\ \cline{2-4} global and shared memory & \multicolumn{4}{c|}{No} & \multicolumn{4}{c}{} \\ \end{tabular}
\end{table} 
Table 3: Technical specifications and feature support per compute capability (Selected from Tables F-1 and F-2 of [36]). Figure 5: GPU-based parallel correlator design. The operations of single thread block (256 threads) on inphase data with a prompt C/A code replica are illustrated here. Thread blocks perform similar operations every millisecond on quadrature data with an early and a late code replica as well. Total 27 thread blocks are needed for each tracking channel, and total 60 tracking channels are needed for the CRPA processing. per thread, and the allocated shared memory per thread block. Once these three design parameters are determined, the GPU occupancy of the design can be calculated using the CUDA GPU occupancy calculator [42]. After several design iterations, we assign 256 threads (or eight warps) per thread block and five thread blocks per multiprocessor. In CUDA, threads are executed in groups of 32 threads. This 32-thread group is called a \"warp\". A multiprocessor of GTX 480 can have 48 active warps (Table 3). Thus, when each thread block has eight warps and six thread blocks are assigned to each multiprocessor, a 100% GPU occupancy (_i.e._, all 48 warps in use) can be achieved. However, our design is limited by the number of registers per multiprocessor (the physical limit is 32 K registers per multiprocessor as shown in Table 3) and only five thread blocks can be assigned to each multiprocessor. Hence, 5 block / multiprocessor\(\times\)8 warp / block = 40 warp / multiprocessor are assigned. The GPU occupancy in this case is 40 warp / 48 warp = 83.33%.