绘制julia集的曲线--GPU高性能编程CUDA实战4.2.2

来源:互联网 发布:网络机顶盒哪个好 编辑:程序博客网 时间:2024/04/28 21:12
#include "../common/book.h"#include "../common/cpu_bitmap.h"//自学的一个CUDA比较有趣的编程,我也来写写注释
#define DIM 1000struct cuComplex {    float   r;    float   i;
//这里的话就是原来少些了个__device__,这是结构体的构造函数,在julia()里使用了,然后Julia()是设备端的函数,所以这里也需要加上,要不然没有办法运行的    __device__ 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.r + r*a.i);    }    __device__ cuComplex operator+(const cuComplex& a) {        return cuComplex(r+a.r, i+a.i);    }};//设备端调用,在设备端运行的都要加__device__,如果是在主机端调用,设备端执行的,那就是Kernel函数,用的是__global____device__ int julia( int x, int y ) {
//这里是为了让图像更大,选择了1.5倍,还有下面的两句为了是图像开始时候位于窗口的中心    const float scale = 1.5;    float jx = scale * (float)(DIM/2 - x)/(DIM/2);    float jy = scale * (float)(DIM/2 - y)/(DIM/2);//这里的常数C在书上写着:这个值刚好能生成一张有趣的图片    cuComplex c(-0.8, 0.156);    cuComplex a(jx, jy);//执行迭代运算,判断该像素点是不是属于Julia集,是的返回值是1,    int i = 0;    for (i=0; i<200; i++) {        a = a * a + c;        if (a.magnitude2() > 1000)            return 0;    }    return 1;}__global__ void kernel( unsigned char *ptr ) {
//这里是索引,dim3里定义的是二维线程格(其实是三维的,最后一维默认为1)所以里面的block里有x和y两维索引
    // map from blockIdx to pixel position    int x = blockIdx.x;    int y = blockIdx.y;    int offset = x + y * gridDim.x;
//一开始我还不是很明白,后来在看头文件的时候慢慢的明白了些,不过还是迷乱,这里是没个像素有4个字节,所以索引之后要乘以4才能找到对应像素的位置,然后这四个字节表示的是RGBA模型,第一个是代表红色
<div style="text-indent: 28px;">//第二个代表绿色,第三个代表蓝色,也就是说如果是在Julia集上,会显示蓝色,0-255代表的是亮度,255就是蓝色。其余的就是黑色的,黑色是哪里来的我还不是很清楚,如果有看到的可以给我解释一下嘛,哈哈,<span style="font-size:12px;">最后的</span>一个字节表示的是<span style="font-family:arial, 宋体, sans-serif;font-size:12px;color:#333333;"><span style="line-height: 24px; ">不透明参数,值在0-1直接,1的话就是不透明的。</span></span></div>    // now calculate the value at that position    int juliaValue = julia( x, y );    ptr[offset*4 + 0] = 0;    ptr[offset*4 + 1] = 0;    ptr[offset*4 + 2] =255* juliaValue;    ptr[offset*4 + 3] = 1;}
//这里在书里是没有的,bitmap()函数里也没有第三个参数,书上的很好理解,这里突然出现两个一样的指针听迷惑的,于是就去cpu_bitmap.h里看一看,里面仅有的一个构造函数是三个参数的// globals needed by the update routine,结构体就相当于类,看起来挺棒,之前我怎么不知道。struct DataBlock {    unsigned char   *dev_bitmap;};//剩下的都是头文件里的函数可以直接调用,没什么好说的,其实关于里面的GLUT我想知道的还有很多呢。。。int main( void ) {    DataBlock   data;    CPUBitmap bitmap( DIM, DIM, &data );    unsigned char    *dev_bitmap;    HANDLE_ERROR( cudaMalloc( (void**)&dev_bitmap, bitmap.image_size() ) );    data.dev_bitmap = dev_bitmap;    dim3    grid(DIM,DIM);    kernel<<<grid,1>>>( dev_bitmap );    HANDLE_ERROR( cudaMemcpy( bitmap.get_ptr(), dev_bitmap,                              bitmap.image_size(),                              cudaMemcpyDeviceToHost ) );                                  HANDLE_ERROR( cudaFree( dev_bitmap ) );                                  bitmap.display_and_exit();}

运行出来的结果是这样的,很好看的


那么 问题就来了,我想要分享一下这个程序,调试出来之后生成的应用程序不是可以直接打开嘛,然后在别的电脑上打开就会告诉我运行出现错误

有几个问题,第一个是我把.exe文件单独拉出了运行,告诉我缺少glut.dll文件,我知道我在SYSTEM文件夹里存了这个,我调试用的32位,运行的时候我用把这个文件放到了SysWOW64文件夹里,然后可以运行了,其实后来直接把他们直接放在一个文件夹里就好了

于是第二个问题,我打包发给朋友,然后运行缺少cudart.dll于是我把这个文件也放在了一个文件夹下,就是下图


然后不会报错了,只是运行一闪,看到两行代码,然后不会出现照片,正常的情况是直接出来个框框,然后紧接着出来上面的图像才对,我改怎么办才能在别的电脑上运行呢???

我好想知道,存疑,还没有解决!


1 0
原创粉丝点击