d2 $note ((scaleP scalePattern$ (rotR 3.5) -- $inversion \n$ (+ slow 8 "x" <~> ((0.5 ~>) generateMelodicSeed)) -- $slow 2 \n$ generateMelodicSeed ) - 12)#s "[pe-gtr:9,midi]" #gain 1.2 #orbit 1 #midichan 2   d4 -- $rev \n$ note ((scaleP scalePattern -- $off 4 ((+ 2 ).slow 2) \n --$ off 1 (inversion.slow 2) \n $(rotR 1.5 )$(+ slow 8 "x" <~> generateMelodicSeed) -- $inversion \n$ generateMelodicSeed ))#s "[pe-gtr:12,midi]" #gain 1.2 #orbit 3 #midichan 4   let melody = slow 6 $"0 2 [4 8 .] [3 4 3] 8 4 9"   generateMelodicSeed = slow 4$ linger 0.5 $repeatCycles 3 --$ palindrome \n $(+ (slow (irand (4)+1) (sometimes (inversion) (run (irand (4)+1)))))$ slow ((irand 3) + 1) $e ("x"<~>(irand 8)) 8$ "x*16"<~>(irand 5) 

# Loop Unrolling

Loop unrolling is an optimization that is typically made by the compiler, although it can be manually accomplished in assembly. When an iteration occurs in the code, and the number of times the iteration loops is known at compile time, the loop can be unrolled. Unrolling the loop means replacing the iteration instruction with hard-coded instructions for each iteration one after the other. For example, consider the following loop:

for (size_t index=0; index<3; index++){
std::cout<<index;
}


The unrolled version is:

std::cout<<1;
std::cout<<2;
std::cout<<3;


Since we know we are going to loop 3 times when we compile, we can replace the loop with hard-coded instructions. The resulting assembly is much faster than conditionally looping.