A good method for the operation of a prime number program is to output only the primes between an upper-bound and the upper-bound - k . Then the program just appears to be jumping from one section of a list to the other on each computation. Of course required consecutive primes are obviously found within the range of the output.
Here is my previous post:
Odd numbers can be wheeled in multiplications to output only odd composite numbers. Then the odd numbers that are not output are the prime numbers.
Now each inner loop can stop at a multiplication that reaches the value of an upper-bound and the outer loop can stop at the square root of the upper-bound.
Furthermore the loops from the number 11 can increment with 2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10 ... as continuing and repeating. That's a big performance gain because multiples of 3, 5, and 7 are removed from the sequence of odd numbers.
A prime number application really works best when outputting prime numbers between an upper bound and the upper bound - k. Then the application appears to be just scrolling sections (or jumping to sections) of a list on each computation. And in this case the loop increments are really only needed on the outer loop because a single division operation jumps over unneeded sections of the inner loop. Of course, array subscript locations can work with translations such that the same array can handle any of the segmented computations and then not use very much memory.