我正在学习如何在 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 倍的运行时间?)
计数质数高达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;
}