views:

168

answers:

3

Hi i want to optimize the following code. It tries to find all coprimes in a given range by comparing them to n. But i want to make it run faster... any ideas?

#include <iostream>

using namespace std;

int GCD(int a, int b)
{
    while( 1 )
    {
        a = a % b;
  if( a == 0 )
   return b;
  b = b % a;

        if( b == 0 )
   return a;
    }
}


int main(void){
 int t;
 cin >> t;
 for(int i=0; i<t; i++){
  int n,a,b;
  cin >> n >> a >> b;

  int c = 0;
  for(int j=a; j<=b; j++){
   if(GCD(j, n) == 1) c++;
  }

  cout << c << endl;
 }

 return 0;
}
+2  A: 

On a single core computer it's not going to get much faster than it currently is. So you want to utilize multiple cores or even multiple computers. Parallelize and distribute.

Since each pair of numbers you want to calculate the GCD for isn't linked to any other pair of numbers you can easily modify your program to utilize multiple cores by using threads.

If this still isn't fast enough you'd better start thinking of using distributed computing, assigning the work to many computers. This is a bit trickier but should improve the performance the most if the search space is large.

Sani Huttunen
how do i use threads?
Richard González Alberto
@Richard González Alberto: Have a look at Boost::Thread http://www.boost.org/doc/libs/1_44_0/doc/html/thread.html
Adrian Grigore
thanks, but that doesn't work for me, i need something from the standard C++ library. Can't use external libraries.
Richard González Alberto
@Richard: You can't write a multithreaded program using only the C++ standard library. You either need to use a third party library to write portable multithreaded code or you need to use your OS or runtime's platform-specific multithreading libraries.
James McNellis
Is 10^5 times faster not much?
liori
yep, but i can't use any of those, contest rules... ;) but thanks anyway.
Richard González Alberto
A: 

Consider giving it a try with doubles. It said that divisions with doubles are faster on typical intel chips. Integer division is the slowest instruction out there. This is a chicken egg problem. Nobody uses them because they're slow and intel doesnt make it faster because nobody uses it.

jdv
can i use % with doubles?
Richard González Alberto
You can't use the `%` operator, but the `fmod` function does the same thing.
Ben Voigt
i'll give this a try. thanks.
Richard González Alberto
If you want to optimize the GCD, use the binary GCD, which does not use any div/mod operations. But that won't come even close to liori's solution.
Accipitridae
+5  A: 

This smells like homework, so only a hint.

You don't need to calculate GCD here. If you can factorize n (even in the crudest way of trying to divide by every odd number smaller than 2^16), then you can just count numbers which happen not to divide by factors of n.

Note that there will be at most 10 factors of a 32-bit number (we don't need to remember how many times given prime is used in factorization).

How to do that? Try to count non-coprimes using inclusion–exclusion principle. You will have at most 1023 subsets of primes to check, for every subset you need to calculate how many multiplies are in the range, which is constant time for each subset.

Anyway, my code works in no time now:

liori:~/gg% time ./moje <<< "1 1003917915 1 1003917915"
328458240
./moje <<< "1 1003917915 1 1003917915"  0,00s user 0,00s system 0% cpu 0,002 total
liori
no, it's not a homework...lol... i'm styding for this year's ICPC. yet thanks for the tip. I'll let you know as soon as i test it. :)
Richard González Alberto