GPU实现julia集曲线
来源:互联网 发布:淘宝怎么看每日好店 编辑:程序博客网 时间:2024/04/29 04:17
julia集是满足某个复数计算函数的所有点构成的边界。对于函数参数的所有取值,生成的边界将形成一种不规则的碎片形状,这是数学中最有趣和最漂亮的形状之一。
生成julia的算法非常简单,Julia集的基本算法是,通过一个简单的迭代等式对复平面中的点求值,如果在计算某个点时,迭代等式的计算结果是发散的,那么这个点就不属于Julia集合,相反,如果在迭代等式中计算得到的一系列值都位于某个边界范围之内,那么这个点就属于Julia集合。迭代等式为:
Z(n+1)=Z(n)*Z(n)+C
基于GPU的Julia集的算法如下:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<cutil.h>
#include<cpu_bitmap.h>// 该头文件打不开
#define DIM 128
//基于GPU的Julia集
/*__device__修饰符表示代码将在GPU上而不是主机上运行。只能从其他__device__
函数或者从__gloabl__函数中调用它们。
*/
struct cuComplex
{
float r;
float i;
cuComplex(float a,float b):r(a),i(b){}
//成员函数,模的平方
__device__ float magnitude2(void)
{ return r*r+i*i; }
//成员函数,复数乘法的重载
__device__ cuComplex operator*(const cuComplex&a)
{ return cuComplex(r*a.r-i*a.i,i*a.i+r*a.i); }
//成员函数,复数加法的重载
__device__ cuComplex operator+(const cuComplex& a)
{ return cuComplex(r=a.r,i+a.i); }
};
//函数功能,将像素转换为得数
__device__ int julia(int x,int y)
{
const float scale=1.5;//放大系数
float jx=scale*(float)(DIM/2-x)/(DIM/2);
float jy=scale*(float)(DIM/2-y)/(DIM/2);
cuComplex c(-0.8,0.156);//迭代函数中常量的定义
cuComplex a(jx,jy);//迭代函数中Z变量的初值
int i=0;
for(i=0;i<200;i++)
{
a=a*a+c;
if(a.magnitude2()>1000)//模的平方大于1000的话,则说明发散,不属于julia集
return 0;
}
return 1;//Z属于julia集,则返加1
}
/*第一步:将kernel声明为一个__global__ 类型的函数。线程格每一维的
大小与图像每一维大小是相等的,因些在(0,0)
和(DIM-1,DIM-1)之间的每个像素点都能获得一个线程块
第二步:得到输出 缓冲区ptr中的线性偏移,这个偏移是通中另一个
内置变量girdDim来计算的,对所有的线程块来说,gidDim是一个常数,
用来保存线程格第一维的大小.在示例中,gridDim的值是(DIM,DIM), 因此,
将行索引乘以线程格的宽,再加上列索引,就得到了ptr中的唯一索引,
其取值范围为(DIM*DIM-1)。
最后分析判断某个点是否属于Julia集的代码。
*/
__global__ void kernel(unsigned char *ptr)
{
//将threadIdx/BlockIdx映身到像素位置
int x=blockIdx.x;
int y=blockIdx.y;
int offset=x+y*gridDim.x;
//计算这个位置上的值
int juliaValue=julia(x,y);
ptr[offset*4+0]=255*juliaValue;
ptr[offset*4+1]=0;
ptr[offset*4+2]=0;
ptr[offset*4+3]=255;
}
int main(void)
{
CPUBitmap bitmap(DIM,DIM);//定义位图对象
unsigned char *dev_bitmap;//用来保存设备上数据的副本。
//申请内存空间
HANDLE_ERROR(cudaMalloc((void**)&dev_bitmap,bitmap.image_size()));
dim3 grid(DIM,DIM);//声明二维的线程格,每个线程都要执行kernel函数的一个副本。
kernel<<<grid,1>>>(dev_bitmap);//将dim3的变量grid传递给CUDA运行时
//将处理结果复制回主机,复制方向中指定为从设备到主机
HANDLE_ERROR(cudaMemcpy(bitmap.get_ptr(),dev_bitmap,bitmap.image_size(),cudaMemcpyDeviceToHost));
bitmap.display_and_exit();
cudaFree(dev_bitmap);
}
程序写完了,但在编译时,由于不认cpu_bitmap头文件,所以本程序没能运行。
- GPU实现julia集曲线
- 绘制julia集的曲线--GPU高性能编程CUDA实战4.2.2
- Julia曲线绘制-——CPU版本与GPU版本对比
- GPU高性能编程CUDA实战——Julia曲线生成错误
- Julia On GPU
- Julia曲线的生成
- [菜鸟每天来段CUDA_C]基于GPU的Julia集
- Julia: Gadfly画三条曲线,打上Label!
- Julia集与Mandelbrot集
- 【计算机图形学】五、Julia集
- Julia : 如何一行实现99乘法表?
- Julia分形算法VC++实现
- 利用CUDA和opencv绘制Julia集
- CUDA By Example 第四章Julia集
- 数学之美之分形——C++及OpenCV实现Julia集和Mandelbrot集绘制
- 玄学曲线并不玄 教你如何看懂GPU呈现
- 玄学曲线并不玄 教你如何看懂GPU呈现
- GPU库伦求和实现
- CentOS下安装tar包/rpm包
- 整数大数加法
- Oracle Relink RAC Binary Options 说明
- topcoder SRM div 2 level 1
- Install Cloudera CDH3 on Ubuntu 11.04 单机
- GPU实现julia集曲线
- topcoder SRM 500 div2 level3
- Android 读取<meta-data>元素的数据
- SDIO接口
- topcoder SRM 501 div1 level1
- python 爬虫基本知识
- 比洗牙更好 教你5分钟消灭牙垢
- 查找关键字(输出文件名和关键字所在行号)
- linux__ 信号__操作