在理想情况下,编译器使用自动并行化能够管理一切事务,使用OpenMP指令的一个优点是将并行性和算法分离,阅读代码时候无需考虑并行化是如何实现的。当然for循环是可以并行化处理的天然材料,满足一些约束的for循环可以方便的使用OpenMP进行傻瓜化的并行。

为了使用自动并行化对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的显示部分:

#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子句:

  schedule(type[, size]),

  参数type是指调度的类型,可以取值为static,dynamic,guided,runtime四种值。其中runtime允许在运行时确定调度类型,因此实际调度策略只有前面三种。

  参数size表示每次调度的迭代数量,必须是整数。该参数是可选的。当type的值是runtime时,不能够使用该参数。

动态调度dynamic

  动态调度依赖于运行时的状态动态确定线程所执行的迭代,也就是线程执行完已经分配的任务后,会去领取还有的任务。由于线程启动和执行完的时间不确定,所以迭代被分配到哪个线程是无法事先知道的。

  当不使用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

OpenMP并行化实例----Mandelbrot集合并行化计算的更多相关文章

  1. Mandelbrot集合及其渲染

    什么是Mandelbrot集合? Mandelbrot集合是在复数平面上组成分形的点的集合,它正是以数学家Mandelbrot命名. Mandelbrot集合可以用复二次多项式 \[ f_c(z)=z ...

  2. 百度地图api 实例 自动提示 并计算两地的行驶距离

    百度地图api 实例 自动提示 并计算两地的行驶距离 <!DOCTYPE html> <html> <head> <meta http-equiv=" ...

  3. 方阵行列式并行化计算(OpenMP,MPI),并计算加速比

    00][100].在创建方阵时,方阵的阶数N(N<100)由外部输入.然后用两层"for循环"来给方阵 p左上角 N×N个位置赋值.具体实现如下: /* * 定义矩阵阶数N ...

  4. OpenMP并行程序设计——for循环并行化详解

    在C/C++中使用OpenMP优化代码方便又简单,代码中需要并行处理的往往是一些比较耗时的for循环,所以重点介绍一下OpenMP中for循环的应用.个人感觉只要掌握了文中讲的这些就足够了,如果想要学 ...

  5. JavaScript实例技巧精选(12)—计算星座与属相

    >>点击这里下载完整html源码<< 这是截图: 核心代码如下: <SCRIPT LANGUAGE="JavaScript"> <!-- ...

  6. Javascript实例技巧精选(8)—计算当月剩余天数

    >>点击这里下载完整html源码<< 截图如下: 利用Javascript在网页上计算当前月份的剩余天数,相应代码如下: <script language="J ...

  7. Fortran+ OpenMP实现实例

    PROGRAM parallel_01 USE omp_lib IMPLICIT NONE INTEGER :: i,j INTEGER() :: time_begin, time_end, time ...

  8. Bluetooth篇 开发实例之六 蓝牙RSSI计算距离

    计算公式: d = 10^((abs(RSSI) - A) / (10 * n)) 其中: d - 计算所得距离 RSSI - 接收信号强度(负值) A - 发射端和接收端相隔1米时的信号强度 n - ...

  9. 一起talk C栗子吧(第三十四回:C语言实例--巧用溢出计算最值)

    各位看官们.大家好,上一回中咱们说的是巧用移位的样例,这一回咱们说的样例是:巧用溢出计算最值. 闲话休提,言归正转.让我们一起talk C栗子吧! 大家都知道,程序中的变量都有一个取值范围,这个范围也 ...

随机推荐

  1. Codeforces278E Tourists

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给定一张无向图,有点权,要支持单点修改点权和询问从一个点到另一个点不重复经过节点的路径上点权最小值的最小值. n,m<=10^5 考虑求 ...

  2. [NOI2012]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 一天一套noi 简直了.... 昨天勉强做完了noi2011 今天教练又丢出来一套noi2012  去掉提答还有5题 勉强做了3题  先占个坑 ...

  3. bzoj2442[Usaco2011 Open]修剪草坪 单调队列优化dp

    2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1159  Solved: 593[Submit] ...

  4. 主席树(BZOJ2653)

    考虑二分答案,设为k,将大于等于k的元素设为1,小于的设为-1,如果某一段的和>=0,说明这段的中位数>=k. 对于每组询问,二分完后查询新序列的最大子段和即可. 但是不能开n棵线段树,观 ...

  5. SpringCloud学习之sleuth&zipkin

    一.调用链跟踪的必要性 首先我们简单来看一下下单到支付的过程,别的不多说,在业务复杂的时候往往服务会一层接一层的调用,当某一服务环节出现响应缓慢时会影响整个服务的响应速度,由于业务调用层次很“深”,那 ...

  6. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现教程

    视频中的物体识别 摘要 物体识别(Object Recognition)在计算机视觉领域里指的是在一张图像或一组视频序列中找到给定的物体.本文主要是利用谷歌开源TensorFlow Object De ...

  7. (概念)多个CPU和多核CPU以及超线程(Hyper-Threading)

    引言 在这篇文章中我会主要介绍CPU相关的一些重要概念和技术.如果你想更好地了解操作系统,那就从本文开始吧. 中央处理器(Central processing unit) 在我们了解其它概念之前,我们 ...

  8. Springboot整合log4j2【详细步骤】

    1.去除logback中的依赖包 <dependency> <groupId>org.springframework.boot</groupId> <arti ...

  9. [ 学习笔记 ] Hibernate框架学习之一

    一.JavaEE开发三层结构和三大框架的对应关系: Struts2框架 -> 表现层 web层(MVC是表现层的设计模型) 业务层 service层 Hibernate框架 -> 持久层 ...

  10. Spring Boot 参数校验

    1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ...