私は素朴な素数生成関数を使用していました。このコードは、10,000 個の素数を生成するのに約 5.25 秒かかります (device_primes[0] は、既に見つかった素数の数と、素数が見つかった残りの位置を保持します)。
_global__ void getPrimes(int *device_primes,int n)
{
int c = 0;
int thread_id = blockIdx.x * blockDim.x + threadIdx.x;
int num = thread_id+2;
if (thread_id == 0) device_primes[0] = 1;
__syncthreads();
while(device_primes[0] < n)
{
for (c = 2; c <= num - 1; c++)
{
if (num % c == 0) //not prime
{
break;
}
}
if (c == num) //prime
{
int pos = atomicAdd(&device_primes[0],1);
device_primes[pos] = num;
}
num += blockDim.x * gridDim.x; // Next number for this thread
}
}
コードの最適化を始めたばかりで、代わりに次の変更を加えました。
for (c = 2; c <= num - 1; c++)
{
if (num % c == 0) //not prime
break;
}
if (c == num) {...}
私が今持っています :
int prime = 1;
...
for (c = 2; c <= num - 1 && prime; c++)
{
if (num % c == 0) prime = 0; // not prime
}
if (prime) {...} // if prime
これで、0.707 秒で 10k を生成できます。なぜこの単純な変更でこのような速度が上がるのか疑問に思っていましたが、ブレークはそれほど悪いのでしょうか?