#include "stdafx.h"
#include <omp.h>
#include<Windows.h>
#include<cmath>
#include<time.h>
#define N 100000
int _tmain(int argc, _TCHAR* argv[])
{
omp_set_num_threads(2);
int i, j, num = 0;
clock_t t1,t2,t3,t4,t5,t6;
t1=clock();
#pragma omp parallel for reduction(+:num)private(j)
for(i=2; i<=N; i++)
{ for(j=2; j<i; j++)
if(i%j==0 ) break;
if( j>=i )
//{
num++;
//printf("线程ID=%d,素数是=%d\n",omp_get_thread_num(),i);
//}
}
t2=clock();
printf("素数共有%d个\n",num);
t5=t2-t1;
printf("并行时间是%lf\n",double(t5));
num=0;
t3=clock();
for(i=2; i<=N; i++)
{ for(j=2; j<i; j++)
if(i%j==0 ) break;
if( j>=i )
//{
num++;
//printf("线程ID=%d,素数是=%d\n",omp_get_thread_num(),i);
//}
}
t4=clock();
printf("素数共有%d个\n",num);
t6=t4-t3;
printf("串行时间是%lf\n",double(t6));
printf("加速比是 %lf",double(t6)/double(t5));
system("pause");
return 0;
}
正确代码二:
#include "stdafx.h"
#include <omp.h>
#include<Windows.h>
#include<cmath>
#include<time.h>
#define N 10000000
#define NUM_THREADS 2
int isPrime(int n)
{
int i;
for(i=2;i<=sqrt(1.0*n);i++)
if(n%i==0) return 0;
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
omp_set_num_threads(NUM_THREADS);
int i, num = 0;
clock_t t1,t2,t3,t4,t5,t6;
t1=clock();
#pragma omp parallel for reduction(+:num)
for(i=2;i<=N;i++)
{
num+=isPrime(i);
}
t2=clock();
printf("素数共有%d个\n",num);
t5=t2-t1;
printf("并行时间是%.9f\n",double(t5));
num=0;
t3=clock();
for(i=2;i<=N;i++)
{
num+=isPrime(i);
}
t4=clock();
t6=t4-t3;
printf("素数共有%d个\n",num);
printf("串行时间是%.9f\n",double(t6));
printf("加速比是 %.9f",double(t6)/double(t5));
system("pause");
return 0;
}
问题以及解决方法
当并行指令是#pragma omp parallel for reduction(+:num)时候出错
改为#pragma omp parallel for reduction(+:num)private(j)即可,因为j在声明时候是共有变量,在执行#pragma omp parallel for时候会创建两个线程,引发数据竞争使结果出错
另外在串行和并行时候直接调用isPrime()函数更不容易出错
还可以用sections-section自动划分线程任务