# Parallel Improvements of the Jaya Optimization Algorithm
## 3 Parallel Approaches
\[F_{min}=\sum_{i=1}^{VAR}\left[100\left(x_{i}^{2}-x_{i+1}\right)^{2}+\left(1-x_{ i}\right)^{2}\right]. \tag{2}\]  
Algorithm 3 shows the skeleton of the shared memory parallel approach of Algorithm 1. Algorithm 3 focuses on the number of performed population updates (i.e., \"Iterations\"), distributing these population updates among the c available processes (\(r=1,2,\ldots,c\)). In Algorithm 3,\(\sum_{r=1}^{c}Iterations_{r}=Iterations\) must be satisfied, where \(Iterations_{r}\) is the number of population updates performed by process \(r\), since a dynamic scheduling strategy has been used the number of populations updates per thread is not a fixed number. Since this algorithm has been designed for shared memory platforms, all solutions are stored in memory using OpenMP. Consequently, following parallel computation, the \"sequential thread (or process)\" obtains the best global solution and computes statistical values of all solutions obtained. As aforementioned, the number of iterations performed by each thread is not fixed, this number depends on the computational load assigned to each core in each particular execution, the automatic load balancing is implemented using the dynamic scheduling strategy of the OpenMP parallel loops. It should be noted that the total number of functions evaluations remains unchanged. ```
1:Update Population:
2:{
3:[Obtain the current best and worst solution]
4:\(F^{worst}=F(Mem^{1})\)
5:\(Index^{worst}=1\)
6:\(F^{best}=F(Mem^{1})\)
7:\(Index^{best}=1\)
8:for\(k=2\) to \(PopulationSize\)do
9:if\(F^{best}>F(Mem^{k})\)then
10:\(Index^{best}=k\)
11:\(F^{best}=F(Mem^{k})\)
12:endif
13:if\(F^{worst}<F(Mem^{k})\)then
14:\(Index^{worst}=k\)
15:\(F^{worst}=F(Mem^{k})\)
16:endif
17:endfor
18:for\(k=1\) to \(PopulationSize\)do
19:\(old=k\)
20:for\(j=1\) to \(VARS\)do
21: Obtain 2 random numbers
22: Compute the design variable of the new member \(NewM_{j}\) {using Equation (1)}
23: Check the bounds of \(NewM_{j}\)
24:endfor
25: Compute \(F(NewM)\) {Function evaluation}
26:if\(F(NewM)<F(Mem^{old})\)then
27: {Replace solution}
28:for\(j=1\) to \(VARS\)do
29:\(Mem^{old}_{j}=NewM_{j}\)
30:endfor
31:endif
32:endfor
33: [Search for current best and worst solution as in Lines 4-17]
34: }
```  
**Algorithm 2** Update Population function of the Jaya algorithm  
Regarding Algorithms 2 and 3, data dependencies exist in the \"Update Population\" function solved in Algorithm 4, which shows the parallel \"Update Population\" function used in Algorithm 1. It should be noted that, to solve these data dependencies, Algorithm 4 includes up to 2 flush memory operations (Lines 3 and 35) and up to 3 critical sections (Lines 18, 26, and 44). It should be noted that only the \"flush\" procedure of Line 3 is performed in all iterations, and the rest of the flush and critical sections depends on the particular and non-deterministic computation. An analysis of data dependencies of the \"Update Population\" function reveals that its corresponding parallel function must be designed for shared memory platforms. It should be noted that the \"flush\" operations are performed to ensure that all threads have the same view of memory variables in which current best and worst solutions are stored. Furthermore, critical sections are used to avoid hazards in memory accesses. Some optimizations have been implemented in Algorithm 4, improving both the computational performance and the Java algorithm behavior. On the one hand, in Line 25 of Algorithm 4, when a new global minimum is obtained, it is quasi immediately used by all processes; on the other hand, in Line 34, the search of the current worst member is performed only by the thread that has removed the previous worst element.