使用全局内存的光线跟踪实验

使用全局内存来存储球面对象,项目打包下载

  1 /*
  2 * Copyright 1993-2010 NVIDIA Corporation.  All rights reserved.
  3 *
  4 * NVIDIA Corporation and its licensors retain all intellectual property and
  5 * proprietary rights in and to this software and related documentation.
  6 * Any use, reproduction, disclosure, or distribution of this software
  7 * and related documentation without an express license agreement from
  8 * NVIDIA Corporation is strictly prohibited.
  9 *
 10 * Please refer to the applicable NVIDIA end user license agreement (EULA)
 11 * associated with this source code for terms and conditions that govern
 12 * your use of this NVIDIA software.
 13 *
 14 */
 15 #include <GL\glut.h>
 16 #include "cuda.h"
 17 #include "cuda_runtime.h"
 18 #include "device_launch_parameters.h"
 19 #include "../common/book.h"
 20 #include "../common/cpu_bitmap.h"
 21 #include "device_functions.h"
 22
 23 #define DIM 1024
 24
 25 #define rnd( x ) (x * rand() / RAND_MAX)
 26 #define INF     2e10f
 27
 28 struct Sphere {
 29     float   r, b, g;
 30     float   radius;
 31     float   x, y, z;
 32     __device__ float hit(float ox, float oy, float *n) {
 33         //将中心坐标移动到图像中间,dx和dy就是相对于新的中心坐标ox和oy的新坐标
 34         float dx = ox - x;
 35         float dy = oy - y;
 36         //只处理点在圆内的Sphere对象
 37         if (dx*dx + dy*dy < radius*radius) {
 38             /*
 39             计算的dz为离圆心轴的距离
 40             */
 41             float dz = sqrtf(radius*radius - dx*dx - dy*dy);
 42             /*
 43             和半径相除,由于dz是float类型,所以结果也为float类型
 44             也就是说结果为0.xxx这样的数字,
 45             n为一个指针,*n为解析指针n,存放的也就是值0.xxx这样的值
 46             呈现在最后的结果就是图像颜色的渐变效果
 47             */
 48             *n = dz / sqrtf(radius * radius);
 49             /*
 50             在三维空间中,已经将xoy投影到为图上,z轴垂直于位图
 51             距离圆心的距离dz再加上原来的Z轴坐标就是当前坐标对应于xoy面的Z轴方向距离
 52             */
 53             return dz + z;
 54         }
 55         return -INF;
 56     }
 57 };
 58 #define SPHERES 20
 59
 60
 61 __global__ void kernel(Sphere *s, unsigned char *ptr) {
 62     // 映射到图像像素上的位置
 63     int x = threadIdx.x + blockIdx.x * blockDim.x;
 64     int y = threadIdx.y + blockIdx.y * blockDim.y;
 65     int offset = x + y * blockDim.x * gridDim.x;//步长
 66     //移动使得Z轴在图像中心
 67     float   ox = (x - DIM / 2);
 68     float   oy = (y - DIM / 2);
 69
 70     float   r = 0, g = 0, b = 0;
 71     float   maxz = -INF;
 72     //每个像素递归判断SPHERES个对象在这个像素点上的值
 73     for (int i = 0; i<SPHERES; i++) {
 74         float   n;
 75         float   t = s[i].hit(ox, oy, &n);
 76         if (t > maxz) {
 77             //这里取n的地址,hit函数将结果存放在&n地址所指的空间,不同的n对应不同的颜色及深度
 78             float fscale = n;
 79             r = s[i].r * fscale;
 80             g = s[i].g * fscale;
 81             b = s[i].b * fscale;
 82             maxz = t;
 83         }
 84     }
 85
 86     ptr[offset * 4 + 0] = (int)(r * 255);
 87     ptr[offset * 4 + 1] = (int)(g * 255);
 88     ptr[offset * 4 + 2] = (int)(b * 255);
 89     ptr[offset * 4 + 3] = 255;
 90 }
 91
 92
 93 // globals needed by the update routine
 94 struct DataBlock {
 95     unsigned char   *dev_bitmap;
 96     Sphere          *s;
 97 };
 98
 99 int main(void) {
100     DataBlock   data;
101     //获取时间
102     cudaEvent_t     start, stop;
103     HANDLE_ERROR(cudaEventCreate(&start));
104     HANDLE_ERROR(cudaEventCreate(&stop));
105     HANDLE_ERROR(cudaEventRecord(start, 0));
106
107     CPUBitmap bitmap(DIM, DIM, &data);
108     unsigned char   *dev_bitmap;
109     Sphere          *s;
110
111
112     // allocate memory on the GPU for the output bitmap
113     HANDLE_ERROR(cudaMalloc((void**)&dev_bitmap,
114         bitmap.image_size()));
115     //在全局内存中分配s
116     HANDLE_ERROR(cudaMalloc((void**)&s,
117         sizeof(Sphere)* SPHERES));
118
119     //主机上申请存储空间
120     Sphere *temp_s = (Sphere*)malloc(sizeof(Sphere)* SPHERES);
121     for (int i = 0; i<SPHERES; i++) {
122         temp_s[i].r = rnd(1.0f);
123         temp_s[i].g = rnd(1.0f);
124         temp_s[i].b = rnd(1.0f);
125         temp_s[i].x = rnd(1000.0f) - 500;
126         temp_s[i].y = rnd(1000.0f) - 500;
127         temp_s[i].z = rnd(1000.0f) - 500;
128         temp_s[i].radius = rnd(100.0f) + 20;
129     }
130     HANDLE_ERROR(cudaMemcpy(s, temp_s,
131         sizeof(Sphere)* SPHERES,
132         cudaMemcpyHostToDevice));
133     free(temp_s);
134
135     // generate a bitmap from our sphere data
136     dim3    grids(DIM / 16, DIM / 16);
137     dim3    threads(16, 16);
138     kernel <<<grids, threads >>>(s, dev_bitmap);
139
140     // copy our bitmap back from the GPU for display
141     HANDLE_ERROR(cudaMemcpy(bitmap.get_ptr(), dev_bitmap,
142         bitmap.image_size(),
143         cudaMemcpyDeviceToHost));
144
145     // get stop time, and display the timing results
146     HANDLE_ERROR(cudaEventRecord(stop, 0));
147     HANDLE_ERROR(cudaEventSynchronize(stop));
148     float   elapsedTime;
149     HANDLE_ERROR(cudaEventElapsedTime(&elapsedTime,
150         start, stop));
151     printf("Time to generate:  %3.1f ms\n", elapsedTime);
152
153     HANDLE_ERROR(cudaEventDestroy(start));
154     HANDLE_ERROR(cudaEventDestroy(stop));
155
156     HANDLE_ERROR(cudaFree(dev_bitmap));
157     HANDLE_ERROR(cudaFree(s));
158
159     // display
160     bitmap.display_and_exit();
161 }

结果如下图所示:

时间: 2024-12-06 14:07:32

使用全局内存的光线跟踪实验的相关文章

数组逆序=全局内存版 VS 共享内存版

全局内存版 1 #include <stdio.h> 2 #include <assert.h> 3 #include "cuda.h" 4 #include "cuda_runtime.h" 5 #include "device_launch_parameters.h" 6 //检查CUDA运行时是否有错误 7 void checkCUDAError(const char* msg); 8 // Part3: 在全局内存

gpu显存(全局内存)在使用时数据对齐的问题

全局存储器,即普通的显存,整个网格中的任意线程都能读写全局存储器的任意位置. 存取延时为400-600 clock cycles  非常容易成为性能瓶颈. 访问显存时,读取和存储必须对齐,宽度为4Byte.如果没有正确的对齐,读写将被编译器拆分为多次操作,降低访存性能. 多个warp的读写操作如果能够满足合并访问,则多次访存操作会被合并成一次完成.合并访问的条件,1.0和1.1的设备要求较严格,1.2及更高能力的设备上放宽了合并访问的条件. 1.2及其更高能力的设备支持对8 bit.16 bit

全局内存性能测试

对10w大小的数组做1w次重复赋值, 分别用多线程和单线程实现. 结果发现 1begin 1 main Time to generate: 50.0 ms 2begin 2 main Time to generate: 117630.0 ms #include <stdio.h> #define MAX_BLOCKS_PER_GRID 65535 #define MAX_BLOCK_ROWS 255 #define MAX_BLOCK_COLS 255 #define MAX_THREADS_

MySQL中内存分为全局内存和线程内存

首先我们来看一个公式,MySQL中内存分为全局内存和线程内存两大部分(其实并不全部,只是影响比较大的 部分): 复制代码 代码如下: per_thread_buffers=(read_buffer_size+read_rnd_buffer_size+sort_buffer_size+thread_stack+join_buffer_size+binlog_cache_size+tmp_table_size)*max_connectionsglobal_buffers=innodb_buffer_

E 全局内存优化

如何使用E语言优化内存,貌似它是一个恒久的问题 我们可以用C++搞定内存 优化,内存优化通常是使用SetProcessWorkingSetSize && EmptyWorkingSet 上面是我编写的一个示例代码,主要使用PSAPI中提供的函 数在上面是使用的通过快照获取进程列表,不过也可以使用 EnumProcesses.cbNeed 有点烦,反正每个看个人的喜好 调用函数: OpenProcess // 打开进程 EmptyWorkingSet // 清除工作区内存 SetProces

gpu显存(全局内存)在使用时数据对齐问题解析

全局存储器,即普通的显存,整个网格中的任意线程都能读写全局存储器的任意位置. 存取延时为400-600 clock cycles  非常容易成为性能瓶颈. 访问显存时,读取和存储必须对齐,宽度为4Byte.如果没有正确的对齐,读写将被编译器拆分为多次操作,降低访存性能. 多个warp的读写操作如果能够满足合并访问,则多次访存操作会被合并成一次完成. 合并访问的条件,GT200放宽了合并访问的条件. 支持对8 bit.16 bit.32 bit.64 bit数据字的合并访问 相应传输32Byte

全局内存

p { margin-bottom: 0.1in; direction: ltr; color: #00000a; line-height: 120%; text-align: justify; orphans: 0; widows: 0 } p.western { font-family: "Calibri", serif; font-size: 10pt } p.cjk { font-family: "DejaVu Sans"; font-size: 10pt

(三)内存 SDRAM 驱动实验

SDRAM 芯片讲解: 地址: 行地址 (A0-A12) 列地址 (A0-A8)    片选信号(BA0 BA1)(L-BANK)(因为SDRAM有 4片) 两片SDRAM 连线唯一区别在 UDQM LDQM DQM0 ---片1 LDQM DQM1----片1 UDQM DQM2----片2  LDQM DQM3---片2   UDQM ———————————————————————————————————————————————————————————— 1.读操作(见杨铸 121) 地址线

GlobalLock锁定一个全局内存对象

GlobalLock BAIPro 原文地址:https://www.cnblogs.com/hshy/p/10885767.html