Parallel processing openmp中的Mandelbrot优化

Parallel processing openmp中的Mandelbrot优化,parallel-processing,openmp,mandelbrot,Parallel Processing,Openmp,Mandelbrot,我必须用C语言并行化mandelbrot程序。我认为我做得很好,我没有更好的时间了。我的问题是,如果有人有改进代码的想法,我一直在思考,也许是在外部和内部之间嵌套的平行区域中 此外,我怀疑是否将所有pragma放在一行或编写单独的pragma(一个用于omp并行、共享和私有变量,一个用于条件,另一个用于omp和schedule dynamic)更优雅或更可取 我怀疑常量是否可以用作私有变量,因为我认为使用常量而不是定义的变量更干净 此外,我还编写了一个条件(如果numpu>1),它没有意义使用并

我必须用C语言并行化mandelbrot程序。我认为我做得很好,我没有更好的时间了。我的问题是,如果有人有改进代码的想法,我一直在思考,也许是在外部和内部之间嵌套的平行区域中

此外,我怀疑是否将所有pragma放在一行或编写单独的pragma(一个用于omp并行、共享和私有变量,一个用于条件,另一个用于omp和schedule dynamic)更优雅或更可取

我怀疑常量是否可以用作私有变量,因为我认为使用常量而不是定义的变量更干净

此外,我还编写了一个条件(如果numpu>1),它没有意义使用并行区域并进行正常的顺序执行

最后,正如我已经阅读的动态块,它取决于硬件和您的系统配置。。。所以我把它作为一个常数,所以它很容易改变

此外,我还根据可用处理器的数量调整线程的数量

 int main(int argc, char *argv[])
{
    omp_set_dynamic(1);

    int xactual, yactual;

    //each iteration, it calculates: newz = oldz*oldz + p, where p is the current pixel, and oldz stars at the origin
    double pr, pi;                   //real and imaginary part of the pixel p
    double newRe, newIm, oldRe, oldIm;   //real and imaginary parts of new and old z
    double zoom = 1, moveX = -0.5, moveY = 0; //you can change these to zoom and change position

    pixel_t *pixels = malloc(sizeof(pixel_t)*IMAGEHEIGHT*IMAGEWIDTH);
    clock_t begin, end;
    double time_spent;    

    begin=clock();

    int numcpu;
    numcpu = omp_get_num_procs();

    //FILE * fp;
    printf("El número de procesadores que utilizaremos es: %d", numcpu);

    omp_set_num_threads(numcpu);

    #pragma omp parallel shared(pixels, moveX, moveY, zoom) private(xactual, yactual, pr, pi, newRe, newIm) (if numcpu>1)
    {
        //int xactual=0;
    //  int yactual=0;
        #pragma omp for  schedule(dynamic, CHUNK)       

    //loop through every pixel
        for(yactual = 0; yactual < IMAGEHEIGHT; yactual++)
            for(xactual = 0; xactual < IMAGEWIDTH; xactual++)
            {
                //calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values
            pr = 1.5 * (xactual - IMAGEWIDTH / 2) / (0.5 * zoom * IMAGEWIDTH) + moveX;
            pi = (yactual - IMAGEHEIGHT / 2) / (0.5 * zoom * IMAGEHEIGHT) + moveY;
            newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0
            //"i" will represent the number of iterations
            int i;
            //start the iteration process
            for(i = 0; i < ITERATIONS; i++)
            {
                //remember value of previous iteration
                oldRe = newRe;
                oldIm = newIm;
                //the actual iteration, the real and imaginary part are calculated
                newRe = oldRe * oldRe - oldIm * oldIm + pr;
                newIm = 2 * oldRe * oldIm + pi;
                //if the point is outside the circle with radius 2: stop
                if((newRe * newRe + newIm * newIm) > 4) break;
            }

            //            color(i % 256, 255, 255 * (i < maxIterations));
            if(i == ITERATIONS)
            {
                //color(0, 0, 0); // black
                pixels[yactual*IMAGEWIDTH+xactual][0] = 0;
                pixels[yactual*IMAGEWIDTH+xactual][1] = 0;
                pixels[yactual*IMAGEWIDTH+xactual][2] = 0;
            }
            else
            {
                double z = sqrt(newRe * newRe + newIm * newIm);
                int brightness = 256 * log2(1.75 + i - log2(log2(z))) / log2((double)ITERATIONS);

                //color(brightness, brightness, 255)
                pixels[yactual*IMAGEWIDTH+xactual][0] = brightness;
                pixels[yactual*IMAGEWIDTH+xactual][1] = brightness;
                pixels[yactual*IMAGEWIDTH+xactual][2] = 255;
            }      

      }

    }   //end of parallel region

    end= clock();

    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    fprintf(stderr, "Elapsed time: %.2lf seconds.\n", time_spent);
intmain(intargc,char*argv[])
{
omp_集_动态(1);
事实上,事实上;
//每次迭代,它都会计算:newz=oldz*oldz+p,其中p是当前像素,oldz在原点开始
double pr,pi;//像素p的实部和虚部
double newRe,newIm,oldRe,oldIm;//新z和旧z的实部和虚部
双缩放=1,moveX=-0.5,moveY=0;//您可以将它们更改为缩放和更改位置
像素*pixels=malloc(sizeof(像素*pixel*t)*图像高度*IMAGEWIDTH);
时钟开始,结束;
花费的时间加倍;
开始=时钟();
int numcpu;
numpu=omp_get_num_procs();
//文件*fp;
printf(“实用程序:%d”,numcpu);
omp_设置_num_线程(numcpu);
#pragma omp并行共享(像素、moveX、moveY、zoom)私有(xactual、yactual、pr、pi、newRe、newIm)(如果numpu>1)
{
//int x实际值=0;
//int-yactual=0;
#计划的pragma omp(动态、块)
//循环遍历每个像素
对于(yactual=0;yactual4)中断;
}
//颜色(i%256255255*(i
您可以扩展实现以利用SIMD扩展。据我所知,最新的OpenMP标准包括向量构造。请查看描述新功能的内容


这说明了在计算Mandelbrot集时如何使用SSE3。

SIMD是一个很好的建议。这是我用来加速Mandelbrot计算的工具之一。是的,提高代码速度的方法是使用SIMD。我使用SSE和AVX来实现。这是针对x86处理器的吗?如果添加SIMD和/或SSE或AVX标记,您将可能会得到更好的答案。您也可能对此处的代码感兴趣: