Julia On GPU

前面已经写了一篇Julia On CPU的文章了。有了这个作为参考,Julia On GPU就好写多了,程序做了些许细微改动。

先上效果图:

Julia On GPU_第1张图片


/*
=========================编译环境=========================
系统: Win7 sp1 32位
CPU: AMD 黑盒5000+ oc到2.7GHz
内存: DDR2 800
显卡: ASUS GTX550Ti
环境: CUDA 5.5 + VisualStudio 2012 Ultimate update3
=========================================================
*/


以下为CUDA代码:

#include 
#include 
#include "common\cpu_bitmap.h"

#define DIM 1000

struct cuComplexGPU
{
	float r, i;
	__device__ cuComplexGPU(float a, float b) : r(a), i(b) {}

	// 复数的模
	// 模∣z∣=√(a^2+b^2) (1)∣z∣≧0 (2)复数模的平方等于这个复数与它的共轭复数的积。
	__device__ float magnitude2()
	{
		return r * r + i * i;
	}

	// 复数乘法
	// z1 = (r + i) z2 = (a.r + a.i)
	// z1 * z2 = (r * a.r - i * a.i) + (r * a.i + i * a.r);
	__device__ cuComplexGPU operator* (const cuComplexGPU &a)
	{
		return cuComplexGPU(r * a.r - i * a.i, i * a.r + r * a.i);
	}

	// 复数加法
	// z1 = (r + i) z2 = (a.r + a.i)
	// z1 + z2 = (r + a.r) + (i + a.i)
	__device__ cuComplexGPU operator+ (const cuComplexGPU &a)
	{
		return cuComplexGPU(r + a.r, i + a.i);
	}
};

__device__ int juliaGPU(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);

	cuComplexGPU c(-0.8, 0.156);
	cuComplexGPU a(jx, jy);

	int i = 0;
	for (int i = 0; i < 200; i++)
	{
		a = a * a + c;
		// 模的平方大于1000,则说明发散,不属于julia集
		if (a.magnitude2() > 1000)
			return 0;
	}

	return 1;
}

__global__ void kernelGPU(unsigned char *ptr)
{
	int x = blockIdx.x;
	int y = blockIdx.y;
	int offset = x + y * gridDim.x;

	int juliaValue = juliaGPU(x, y);
	// 每个颜色用4个字节表示,并给每个字节赋值
	ptr[offset * 4 + 0] = 200 * juliaValue;					// 确定图像的颜色的Red分量
	ptr[offset * 4 + 1] = 90 * juliaValue;					// 确定图像的颜色的Green分量
	ptr[offset * 4 + 2] = 179 * juliaValue;					// 确定图像的颜色的Blue分量
	ptr[offset * 4 + 3] = 255;
}

int main()
{
	CPUBitmap bitmap(DIM, DIM);		// 图像画布大小为 1000x1000
	unsigned char *dev_bitmap;

	cudaMalloc((void**)&dev_bitmap, bitmap.image_size());    // 为此大小的画布分配显存

	dim3 grid(DIM, DIM, 1U);
	kernelGPU<<>>(dev_bitmap);

	cudaMemcpy(bitmap.get_ptr(), dev_bitmap, bitmap.image_size(), cudaMemcpyDeviceToHost);		// 从显存中拷贝数据到内存中
	bitmap.display_and_exit();

	cudaFree(dev_bitmap);

	return 0;
}
注:需要在项目属性中指定lib文件夹

你可能感兴趣的:(CUDA)