OpenMP並行化實例----Mandelbrot集合並行化計算



在理想狀況下,編譯器使用自動並行化可以管理一切事務,使用OpenMP指令的一個優勢是將並行性和算法分離,閱讀代碼時候無需考慮並行化是如何實現的。固然for循環是能夠並行化處理的自然材料,知足一些約束的for循環能夠方便的使用OpenMP進行傻瓜化的並行。html


爲了使用自動並行化對Mandelbrot集合進行計算,必須對代碼進行內聯:書中首次使用自動並行化時候,經過性能分析發現工做在線程中並未平均分配。算法

#include <stdio.h>
#include <malloc.h>
#define SIZE 4000

int inSet(double ix,double iy)
{
	int iterations = 0;
	double x = ix,y = iy;
	double x2 = x*x, y2 = y*y;

	while ((x2 + y2 < 4) && (iterations < 1000))
	{
		y = 2*x*y + iy;
		x = x2 -y2 +ix;
		x2 = x*x;
		y2 = y*y;
		iterations++;
	}

	return iterations;
}

int main()
{
	int *matrix[SIZE];
	for (int i = 0; i < SIZE; i++)
	{
		matrix[i] = (int* )malloc( SIZE*sizeof(int) );
	}

#pragma omp parallel for
	for (int x = 0 ;x <SIZE; x++)
	{
		for (int y =0;y <SIZE;y++)
		{
			double xv = ((double)x -(SIZE/2)) / (SIZE/4);
			double yv = ((double)y -(SIZE/2)) / (SIZE/4);
			matrix[x][y] = inSet(xv,yv);
		}
	}

	for (int x =0; x<SIZE;x++)
	{
		for (int y =0;y<SIZE;y++)
		{
			if (matrix[x][y] == -7)
			{
				printf(" ");
			}
		}
	}

	return 0;
}


    當咱們看到 分形圖的時候應該能夠很快的理解負荷不均衡從那裏產生,分形圖中大部分點不在集合中,這部分點只須要少許的迭代就能夠肯定,但有些在集合中的點則須要大量的迭代。編程

     固然我再一次見識到了OpenMP傻瓜化的並行操做機制,糾正工做負荷不均衡只要更改並行代碼調度子句就能夠了,使用動態指導調度,下面代碼是增長了OpenCV的顯示部分:ide


#include "Fractal.h"
#include <Windows.h>
#include <omp.h>

int Fractal::Iteration(Complex a, Complex c)
{
	double maxModulus = 4.0;
	int maxIter = 256;
	int iter = 0;
	
	Complex temp(0,0) ;

	while ( iter < maxIter && a.modulus() < maxModulus)
	{
		a = a * a ;
		a += c;
		iter++;
	}
	return iter;
}

cv::Mat Fractal::generateFractalImage(Border border, CvScalar colortab[256] )
{
	cv::Size size(500,500);

	double xScale = (border.xMax - border.xMin) / size.width;
	double yScale = (border.yMax - border.yMin) / size.height;

	cv::Mat img(size, CV_8UC3);

#pragma omp parallel for schedule(dynamic)
	for (int y=0; y<size.height; y++)
	{
		for (int x=0; x<size.width; x++)
		{
			double cx = border.xMin + x * xScale;
			double cy = border.yMin + y * yScale;

			Complex a(0.0, 0.0);
			Complex c(cx, cy);
			int nIter ;

			if (type == MANDELBROT)
			{
				nIter = Iteration(a, c);
			}
			else if (type == JUALIA)
			{
				nIter = Iteration(c, offset);
			}

			int colorIndex =  (nIter) % 255;

			cv::Vec3b color;
			color.val[0] = colortab[colorIndex].val[0];
			color.val[1] = colortab[colorIndex].val[1];
			color.val[2] = colortab[colorIndex].val[2];
			img.at<cv::Vec3b>(y,x) = color;
		}
	}

	return img;
}

  #pragma omp parallel for schedule(dynamic) 子句性能

schedule子句:ui

  schedule(type[, size]),spa

  參數type是指調度的類型,能夠取值爲static,dynamic,guided,runtime四種值。其中runtime容許在運行時肯定調度類型,所以實際調度策略只有前面三種。.net

  參數size表示每次調度的迭代數量,必須是整數。該參數是可選的。當type的值是runtime時,不可以使用該參數。線程

動態調度dynamiccode

  動態調度依賴於運行時的狀態動態肯定線程所執行的迭代,也就是線程執行完已經分配的任務後,會去領取還有的任務。因爲線程啓動和執行完的時間不肯定,因此迭代被分配到哪一個線程是沒法事先知道的。

  當不使用size 時,是將迭代逐個地分配到各個線程。當使用size 時,逐個分配size個迭代給各個線程。


動態調度迭代的分配是依賴於運行狀態進行動態肯定的,因此哪一個線程上將會運行哪些迭代是沒法像靜態同樣事先預料的。

加速結果:

1.放大加速結果


2.未加速時候的放到功能,基本是3-5倍這個水平,也就是至關於臺式機cpu 的個數?本人的猜想


3.圖像計算結果(未加速)


4. 動態加速結果


代碼:http://download.csdn.net/detail/wangyaninglm/9516035


參考文獻:


http://baike.baidu.com/view/1777568.htm?fromtitle=Mandelbrot%E9%9B%86%E5%90%88&fromid=1778748&type=syn

http://www.cnblogs.com/easymind223/archive/2013/01/19/2867620.html
戈夫. 多核應用編程實戰[M]. 人民郵電出版社, 2013.

http://openmp.org/mp-documents/OpenMP3.1-CCard.pdf

http://blog.csdn.net/gengshenghong/article/details/7000979

相關文章
相關標籤/搜索