有人能帮我改进这段代码并给我一些提示吗?我试图自己创建一个openmp版本的mandelbrot集。我是openmp初学者,这里我没有得到一些加速,这可能是因为#pragma omp critical,但我现在想不出更好的主意。int main(){ // picture resolution int iX,iY; const int ImageWidth = 1000; const int ImageHeight = 1000; double Cx,Cy; const double CxMin=-2.5; const double CxMax=1.5; const double CyMin=-2.0; const double CyMax=2.0; double PixelWidth=(CxMax-CxMin)/ImageWidth; /* scaled x coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot X scale (-2.5, 1.5) */ double PixelHeight=(CyMax-CyMin)/ImageHeight;/* scaled y coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot Y scale (-2.0, 2.0) */ const int MaxColorComponentValue=255; FILE * fp; char *filename="MandelbrotSet.ppm"; char *comment="# ";// comment in ppm picture should start with # unsigned char color[3]; // colors [R, G ,B] // Z=Zx+Zy*i ; Z0 = 0 double Zx, Zy; double Zx2, Zy2; // Zx2=Zx*Zx; Zy2=Zy*Zy int Iteration; const int IterationMax=150; const double Bailout=2; // bail-out value double Circle_Radius=Bailout*Bailout; // circle radius fp= fopen(filename,"wb"); //write the header to the picture file fprintf(fp,"P6\n %s\n %d\n %d\n %d\n", comment,ImageWidth,ImageHeight,MaxColorComponentValue); // For each pixel on the screen do: // initialize_timer ( ); // start_timer ( ); omp_set_dynamic(1); omp_set_num_threads(4); #pragma omp parallel /*reduced(>:Circle_Radius)*/ { #pragma omp for private(iY,iX,Iteration,Zx,Zy,Zx2,Zy2,color) \ schedule(dynamic) //or runtime for(iY=0;iY<ImageHeight;iY++) { Cy=CyMin + iY*PixelHeight; if (fabs(Cy)< PixelHeight/2) Cy=0.0; // Main antenna #pragma omp critical for(iX=0;iX<ImageWidth;iX++) { Cx=CxMin + iX*PixelWidth; Zx=0.0; Zy=0.0; Zx2=Zx*Zx; Zy2=Zy*Zy; /* */ for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<Circle_Radius);Iteration++) { Zy=2*Zx*Zy + Cy; Zx=Zx2-Zy2 +Cx; Zx2=Zx*Zx; Zy2=Zy*Zy; }; if (Iteration==IterationMax) { // interior of Mandelbrot set = black color[0]=0; color[1]=0; color[2]=0; } // else{ color[0]=180; color[1]=0; color[2]=0; // Gradient((double)(Iteration-log2(log2(sqrt(Zx2+Zy2))))/IterationMax,color); } fwrite(color,1,3,fp); } } } fclose(fp); // stop_timer ( ); // // printf("Elapsed time: %lf\n",elapsed_time ( )); return 0;} 最佳答案 按照 >的方法修复这些结果:不带OpenMP:$ gcc -std=c99 -O3 -march=native mandel.c && time ./a.exereal 0m12.324suser 0m0.000ssys 0m0.000s启用OpenMP时:User@IXL /cygdrive/e/mingw64$ gcc -std=c99 -O3 -march=native -fopenmp mandel.c && time ./a.exereal 0m3.619suser 0m0.000ssys 0m0.015s输出印象: ...:.......... .... .............. ....;.=:./ .............:............ ........::::...... .... .......... .++^ .........^.:.....:;.........................:_::.:.........:::::. .....: ..:.^ ........:::=;:=:.....::....................::=|;:........:....... .....::|:_.,= ..........:::==:;:.:::..............:::.)=;-`|`:-.......:::=,. ...... .....:==.:^ _ ..........:<, ^./;;==:......::.......:_., -<;.........:`_;:............ . ..........-=:_, ...... ...:=' _,;;:.....:=v+`::::==, _,:::=|,.:;=+</+;... ::.:........................._.....' ......._,+;=^ "=:.:=<.:- _. ^ -^ ` "-`. =);)( "= ....:_,......................../=:.;- ...`:::::=-= =;. - _.(:.:..==-:......................+o(. ...........=<_ -^== :.==;...................= :_ .............:^:..., -:::.=<,............... .'-. .... ............:.._.:.=,- .;:;:.............:v-_ ..........:_,....:=`._/ --_.)(.:.........:/". .......:,:;,;:=:::=` r`;,:........ =|` ........-=|=/.--.n` -"-+=........_/ , .. . ........^`:_, =::......._ .._.. ...........::-. ..,:....,. ...... ............._,::< -_,:..:./ ..:...... ...................:.^` -'=::::=` .... .........._..............:`_ i:::` ......:.........::.........:::v (::, .....:_:...:..._;=:..::......:.>= ==; .......:::::|=-:_,=-_.;=.:,:..::<, =` ...........::=o -` ^/):::_^ +.... .....:......:_===^ _=;^ i.................=:.:.::;` _=..................-=+=;; -..:;:...::....:::;%,..:;:...::....:::;(`.................:;;^=;;: _.................::...::;, _/+... ............:-=;=_, _.=`;. i ............::| _:_,.._.. .^":::- + ....... ;:;+``:-`;.=+;-^:`:.._.X` =, ......-:...:...-==:..::......:.>` -=; ......:.........::...........:"_ /::` .... ..........-..............:,/ i:::, ..:...... ...................:^., _,=::::=` ...... .............-`::) _-`:..:+' ..... ...........:;_. !`:......- .. .......:.,:=` -+".......-= ........_,<(=='=;<= _._>,;.......-\ ...: . ...:=;. ..:=` >,|;:........ _=, .:::......:......:{(+=< _==;=/............]v. ...........-.....`.:^_ -` ':;;.............:. / .............:..-^`-` -=|;:^;=`...............:^}\. ...........=>- _.== :.==;...................= :! ...,:::::=_= =;. _ -.(:.:"^==_:......................+o(^ ......-`|;=., _.=:.:-".:` - ._ _., | =+;-< .=:..:::-`........................\=:^<, ...... ..::;, ....-^;::.....;|:=,::::=-` -<=::=^`.::-;<=::... :...........................-.., |, ..........:"=,.+^:;++:......;:..... :={( ..=::."......:;=::......... .......:::-:/` ..........::;;::;:..::..............:.:-^`;__+::........::;-`. .... ....:;=+..__,= ........:_:; :;::........................:::;=;:........::...... .....;<,-.`- .......:::.:.....:;....... ............:=:.^ .........;:.:.. .....: ..:"._, .............:........... .......:::...... ... ........._..- .......... . ... ..:........ .....:=:)( ........... ..:....... ..-.:s%=+'._,_/'_ ........ ...:..... .. :.-<=::"_/_`-+.,代码示例#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include <unistd.h>#include <stdint.h>#include <omp.h>// picture resolutionstatic const int ImageWidth = 1000;static const int ImageHeight = 1000;static const double CxMin = -2.5;static const double CxMax = 1.5;static const double CyMin = -2.0;static const double CyMax = 2.0;int main(){ double PixelWidth=(CxMax-CxMin)/ImageWidth; /* scaled x coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot X scale (-2.5, 1.5) */ double PixelHeight=(CyMax-CyMin)/ImageHeight;/* scaled y coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot Y scale (-2.0, 2.0) */ const int MaxColorComponentValue=1<<8; typedef unsigned char pixel_t[3]; // colors [R, G ,B] pixel_t *pixels = malloc(sizeof(pixel_t)*ImageHeight*ImageWidth); //write the header to the picture file FILE* fp; #pragma omp parallel shared(pixels) { int iY; #pragma omp for for(iY=0; iY<ImageHeight; iY++) { double Cy=CyMin + iY*PixelHeight; if (fabs(Cy)< PixelHeight/2) { Cy=0.0; // Main antenna } int iX; for(iX=0; iX<ImageWidth; iX++) { double Cx=CxMin + iX*PixelWidth; double Zx=0.0; double Zy=0.0; double Zx2=Zx*Zx; double Zy2=Zy*Zy; /* */ int Iteration; const int IterationMax=150; const double Bailout=2; // bail-out value const double Circle_Radius=Bailout*Bailout; // circle radius for (Iteration=0; Iteration<IterationMax && ((Zx2+Zy2)<Circle_Radius); Iteration++) { // Zy=2*Zx*Zy + Cy; Zx=Zx2-Zy2 + Cx; Zx2=Zx*Zx; Zy2=Zy*Zy; }; if (Iteration==IterationMax) { // interior of Mandelbrot set = black pixels[iY*ImageWidth + iX][0] = 0; pixels[iY*ImageWidth + iX][1] = 0; pixels[iY*ImageWidth + iX][2] = 0; } // else { pixels[iY*ImageWidth + iX][0] = ((double)(Iteration-log2(log2(sqrt(Zx2+Zy2))))/IterationMax) * MaxColorComponentValue; pixels[iY*ImageWidth + iX][1] = 0; pixels[iY*ImageWidth + iX][2] = 0; } } } } //return 0; // TO BENCHMARK without free()/file IO //write the header to the picture file fp= fopen("MandelbrotSet.ppm","wb"); fprintf(fp,"P6\n %s\n %d\n %d\n %d\n","# no comment",ImageWidth,ImageHeight,MaxColorComponentValue); for(int iY=0; iY<ImageHeight; iY++) for(int iX=0; iX<ImageWidth; iX++) fwrite(pixels[iY*ImageWidth + iX],1,sizeof(pixel_t),fp); fclose(fp); free(pixels); // stop_timer ( ); // // printf("Elapsed time: %lf\n",elapsed_time ( )); return 0;}1无文件IO的计时(参见代码中return处的注释)
10-05 18:06