OpenMP并行实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
并行实验报告
一、积分计算圆周率
1.1积分计算圆周率的向量优化
1.1.1串行版本的设计
任务:理解积分求圆周率的方法,将其用C代码实现。
、、亠
理论上,dx越小,求得的圆周率越准确;在计算机中由于表"
示的数据是有精度范围的,如果dx太小,积分次数过多,误差积累
导致结果不准确。
以下为串行代码:
#in clude
#in clude
double pi=0.0;
double delta =1.0/dt; int i;
for(i=0; i
}
retur n pi*4;
} int mai n()
{
int dx;
double pai;
double start,fi ni sh;
dx=N;
start二clock();
pai二get_pi(dx);
fini sh=clock();
prin tf("%.8lf\n",pai);
prin tf("%.8lfS\n",(double)(fi ni sh-start)/CLOCKS_PER_SEC); retur n 0; }
第一次:time=0.02674000S
第二次:time=0.02446500S
第三次:time=0.02402800S
三次平均为:0.02508S
1.1.2 SSE向量优化版本设计
任务:此部分需要给出单精度和双精度两个优化版本
(1)测试均在划分度为10的7次方下完成。
以下是SSE双精度的代码:
#i nclude
#in clude
#in clude
#defi ne N 10000000 double get_pi (int dt){
double pi=0.0;
double delta =1.0/dt; int i;
for(i=0; i
}
return pi*4;
} double get_pi_sse(size_t dt){
double pi=0.0;
double delta =1.0/dt;
__m128d xmm0,xmm1,xmm2,xmm3,xmm4; xmm0=_mm_set1_pd(1.0);
xmm1=_mm_set1_pd(delta);
xmm2=_mm_set_pd(delta,0.0); xmm4=_mm_setzero_pd();
for(long int i=0; i<=dt-2; i+=2){
xmm3= _mm_set1_pd((double)i*delta);
xmm3= _mm_add_pd(xmm3,xmm2);
xmm3= _mm_mul_pd(xmm3,xmm3);
xmm3= _mm_add_pd(xmm0,xmm3);
xmm3= _mm_div_pd(xmm1,xmm3);
xmm4= _mm_add_pd(xmm4,xmm3);
} --
double tmp[2] __attribute__((alig ned(16))); _mm_store_pd(tmp,xmm4); pi+=tmp[0]+tmp[1]/*+tmp[2]+tmp[3]*/;
return pi*4.0; } int main()
{
int dx;
double pai;
double start,fi ni sh; dx=N;
start=clock(); pai=get_pi_sse(dx);
fini sh=clock();
prin tf("%.8lf\n",pai);
prin tf("%.8lfS\n",(double)((fi nish-start)/CLOCKS_PER_SEC)); return 0; }
时间运行如下:
第一次:time=0.00837500S
第二次:time=0.00741100S
第三次:time=0.00772000S
三次平均为:0.00783S
以下是SSE单精度的代码:
#i nclude
#in clude
#in clude
#defi ne N 10000000
float get_pi_sse(size_t dt){
float pi=0.0;
float delta =1.0/dt;
__m128 xmm0,xmm1,xmm2,xmm3,xmm4; xmm0=_mm_set1_ps(1.0);
xmm1=_mm_set1_ps(delta);
xmm2=_mm_set_ps(delta*3,delta*2,delta,0.0); xmm4=_mm_setzero_ps();
for(l ong int i=0; i<=dt-4; i+=4){
xmm3= _mm_set1_ps((float)i*delta);
xmm3= _mm_add_ps(xmm3,xmm2);
xmm3= _mm_mul_ps(xmm3,xmm3);
xmm3= _mm_add_ps(xmm0,xmm3);
xmm3= _mm_div_ps(xmm1,xmm3);
xmm4= _mm_add_ps(xmm4,xmm3);