## 3 Our Proposed Approach
### GPU Kernel Optimization  
Since the Okada model has no dependence between point calculations, it is straightforward to implement the model in a CUDA kernel function. We first implemented a sequential C++ Okada model based on the MATLAB open-source [46] and then wrote the CUDA kernel function computing the Okada model. Figure 4 shows the difference between CPU and CUDA implementation. While CPU code sequentially calculates the displacement of the 2D mesh using a nested loop, in parallel implementation, a host code launches the kernel with a specific keyword \"_global_\", and thousands of threads simultaneously execute the kernel function. In the parallel implementation of the Okada model, each thread performs a massive number of arithmetic operations, but there are no shared variables in thread block scope and no thread synchronizations. Therefore, maximizing instruction efficiency can be the prime \begin{table}
\begin{tabular}{c c l} \hline \hline
**Parameter** & **Unit** & **Description** \\ \hline \(E\) & km & Distance from the reference point to the east \\ \(N\) & km & Distance from the reference point to the north \\ _Depth_ & km & Depth of source \\ _Strike_ & degrees & Angle of fault relative north \\ _Dip_ & degrees & Angle between the fault and a horizontal plane \\ _Length_ & km & Length of fault \\ _Width_ & km & Width of fault \\ _Rake_ & degrees & Angle of slip relative to the width direction \\ _Slip_ & cm & Dislocation in rake direction \\ _Open_ & cm & Dislocation in tensile component \\ \hline \hline \end{tabular}
\end{table} 
Table 2: Source parameters of the Okada model. Figure 3: Fault geometry of the Okada model [23]. optimization goal of the Okada model. However, since efficient instructions generally need additional resources, there is a trade-off between the instruction efficiency and the number of active warps that determine thread-level parallelism. We set our optimization goal to minimize the computation time by striking a balance between instruction efficiency and thread-level parallelism. For this purpose, we used two performance metrics: efficiency [47] for instruction efficiency and occupancy [48] for thread-level parallelism. We use the NVIDIA Nsight compute profiling tool to calculate the performance metrics. Efficiency indicates the instruction efficiency of the configuration. It is calculated as the reciprocal of the total number of PTX instructions of the kernel [47], described as Equation (5). Thus, high efficiency means that the kernel can perform the same task with fewer instructions. \[\text{Efficiency}=\frac{1}{\text{The number of instructions}} \tag{5}\]  
Occupancy represents the warp scheduling performance, calculated as Equation (6). Maximizing the number of active warps in SM facilitates hiding the latency caused by the global memory access, branch divergence, or instruction stall. Since a GPU has limited resources such as shared memory, registers, or thread blocks per SMs, inefficient resource usage may decrease the occupancy. \[\text{Occupancy}=\frac{\text{Active warps per SM}}{\text{Maximum warps per SM}} \tag{6}\]  
This paper attempt to obtain the best CUDA optimization configuration by employing the following three techniques. 1. Common subexpression elimination (CSE);
2. Constant caching;
3. Thread block size. There are other CUDA optimization techniques, such as tilling or loop unrolling. However, we did not employ the tiling technique using shared memory because all operations are performed independently in each thread, and there are no variables referenced at the  
Figure 4: Difference between CPU and CUDA implementations. thread block scope. Furthermore, since our implementation has no inner loop, we do not use the loop unrolling technique. CSE removes repeated calculations such as arithmetic or load operation by replacing repeated calculations with the precomputed value from the register, as shown in Figure 5[38]. Since the register reference cost is less than the arithmetic operation cost, CSE can increase the instruction efficiency.