4

有人可以帮我改进这段代码并给我一些提示。我试图自己创建一个 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;
}
4

2 回答 2

5

根据评论修复方法会导致这些时间1

没有 openMP:

$ gcc -std=c99 -O3 -march=native mandel.c && time ./a.exe

real    0m12.324s
user    0m0.000s
sys     0m0.000s

并启用 openMP:

User@IXL /cygdrive/e/mingw64
$ gcc -std=c99 -O3 -march=native -fopenmp mandel.c && time ./a.exe

real    0m3.619s
user    0m0.000s
sys     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 resolution
static 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代码中的注释)

于 2012-12-05T11:41:58.430 回答
1

这是完整的代码。谢谢你帮助我。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <omp.h>
// #include "timer.h"

void Gradient();

// picture resolution
static 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=255;
    typedef unsigned char pixel_t[3]; // colors [R, G ,B]
    pixel_t *pixels = malloc(sizeof(pixel_t)*ImageHeight*ImageWidth);


    FILE* fp;

//     initialize_timer ( );
//     start_timer ( );
    #pragma omp parallel shared(pixels)
    {
        int iY;
        #pragma omp for schedule(dynamic)
        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=50;
                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 {
            Gradient((double)((Iteration-log2(log2(sqrt(Zx2+Zy2)))))/IterationMax,pixels[iY*ImageWidth + iX]);
                }
            }
        }
    }

    fp= fopen("MandelbrotSetNEW.ppm","wb");
    fprintf(fp,"P6\n %s\n %d\n %d\n %d\n","# no comment",ImageWidth,ImageHeight,MaxColorComponentValue);   
    fwrite(pixels,sizeof(pixel_t),ImageWidth*ImageWidth,fp);
    fclose(fp);
    free(pixels);

//     stop_timer ( );
//     
//     printf("Elapsed time: %lf \n",elapsed_time ( ));

    return 0;
}

void Gradient(double position,unsigned char c[3])
{


  if (position>1.0){
    if (position-(int)position==0.0) position=1.0;

    else position=position-(int)position;    
  }




  unsigned char nmax=7; // number of color bars 
  double m=nmax*position;

  int n=(int)m; 

  double f=m-n; 
  unsigned char t=(int)(f*255);



switch( n){
   case 0: {
      c[0] =0;
      c[1] = t;
      c[2] = 255;
       break;
    };
   case 1: {
      c[0] = 0;
      c[1] = 255-t;
      c[2] = 255;
       break;
    };
   case 2: {
      c[0] = t;
      c[1] = 255;
      c[2] = 0;
       break;
    };
   case 3: {
      c[0] = 255;
      c[1] = 255 - t;
      c[2] = 0;
       break;
    };
   case 4: {
      c[0] = t;
      c[1] = 0;
      c[2] = 255;
       break;
    };
   case 5: {
      c[0] = 255;
      c[1] = 0;
      c[2] = 255 - t;
       break;
    };
    default: {
      c[0] = 255;
      c[1] = 0;
      c[2] = 0;
       break;
    };

};

};
于 2012-12-05T14:13:38.707 回答