私は C で OpenMP を使用する方法を学習中であり、HelloWorld の演習として、素数を数えるプログラムを作成しています。次に、これを次のように並列化します。
int numprimes = 0;
#pragma omp parallel for reduction (+:numprimes)
for (i = 1; i <= n; i++)
{
if (is_prime(i) == true)
numprimes ++;
}
gcc -g -Wall -fopenmp -o primes primes.c -lm
このコードを(使用-lm
しているmath.h
関数に対して) を使用してコンパイルします。次に、このコードを で実行するIntel® Core™2 Duo CPU E8400 @ 3.00GHz × 2
と、予想どおり、パフォーマンスはシリアル プログラムよりも優れています。
ただし、これをはるかに強力なマシンで実行しようとすると、問題が発生します。( で使用するスレッド数を手動で設定しようとしましたnum_threads
が、何も変わりませんでした。) までのすべての素数を数えると、 ( を使用して)10 000 000
次の時間が得られます。time
8 コア マシン:
real 0m8.230s
user 0m50.425s
sys 0m0.004s
デュアルコアマシン:
real 0m10.846s
user 0m17.233s
sys 0m0.004s
このパターンは、より多くの素数をカウントするために続きます。より多くのコアを備えたマシンは、わずかなパフォーマンスの向上を示していますが、より多くのコアを使用できる場合に期待するほどではありません。(コアが 4 倍多いということは、実行時間がほぼ 4 分の 1 になることを意味すると思いますか?)
まで素数を数え50 000 000
ます:
8 コア マシン:
real 1m29.056s
user 8m11.695s
sys 0m0.017s
デュアルコアマシン:
real 1m51.119s
user 2m50.519s
sys 0m0.060s
誰かが私のためにこれを明確にすることができれば、それは大歓迎です。
編集
これが私の素数チェック関数です。
static int is_prime(int n)
{
/* handle special cases */
if (n == 0) return 0;
else if (n == 1) return 0;
else if (n == 2) return 1;
int i;
for(i=2;i<=(int)(sqrt((double) n));i++)
if (n%i==0) return 0;
return 1;
}