On Wednesday, 30 October 2013 at 18:56:42 UTC, Zeke wrote:
On Wednesday, 30 October 2013 at 14:17:22 UTC, qznc wrote:
Why do you want to find the exact prime first? Just check against sqrt(num) in the loop.

auto upper = cast(ulong)sqrt(cast(double)num)) + 1;
foreach(ulong prime; primes) {
 if (prime > upper) return true;
 if (num % prime == 0) return false;
}
assert (false); // should be unreachable?

Because having a branch inside the foreach causes a branch prediction error when you've found a prime number. Simply iterating up to the sqrt and then terminating the loop has no branch prediction error. Try it for yourself.

Interesting thought.

In your code, there are two conditional branches in each iteration: The check for the end of foreach range and the prime check. Why is one more condition for the upper check so bad?

I admit, my code includes the superfluous foreach range check. Hence this improved version:

ulong prime;
int i = 0;
assert (primes[$] > upper);
do {
  prime = primes[i];
  if (num % prime == 0) return false;
  i+=1;
} while (prime < upper);
return true;

In this version there is still an implicit bounds check for the array access. For dmd "-noboundscheck" disables that branching.

Optimizing for branch prediction sounds premature, since you are using a slow algorithm anyways. ;)

Reply via email to