光线跟踪Ray Traceing是本章的一个例子,用来讲什么是常量内存(Constant memory),之前的实验给分配的内存都是在全局内存里,线程读取数据的时候是每个线程分别进行一次读取操作,也就是说运行时间都用在了读取上。这就大大的降低了GPU的计算性能。常量内存的好处是读取一次数据,就相当于给半个线程束里同时读取,一个Warp是32个线程,这样读取一次就是完成里全局内存中十六次的读取,时间上就是原来的1/16,但是这是有前提的,每个线程要处理的数据必须是完全一样的,那么之前的点积运算和共享内存那样的位图就不适合了,因为每个线程处理的数据不一样,这样反而会降低读取的速度,那么这个光线跟踪的例子就很好的运用在常量内存中,并提高程序的运行速度。
这里还有个CUDA的事件API,其中一个就是用来计时的,通过计时来观察生成同样的图片所用的时间,来发现常量内存的伟大之处!
cuda中的事件本质是GPU时间戳,由于GPU本身支持记录时间戳,就直接定义一个事件,然后记录一个事件就可以了
cudaEvent_t start;
cudaEventCreate(&start);
cudaEventRecord(start,0);//这个参数为0,有关于流,我还没学到
要统计一段代码的事件,要加上结束的事件,因此,用法应该是这样的:
cudaEvent_t start, stop;
cudaEventCreate( &start ) ;
cudaEventCreate( &stop ) ;
cudaEventRecord( start, 0 ) ;
//这里就是需要执行的代码
cudaEventRecord( stop, 0 ) ;
//GPU和CPU之间是可以并行计算的,GPU在生成计算的过程中,cpu其实可以接着进行下面的语句的,既然是计时,我们自然不让它这么做,所以这个事件就是用来
cudaEventSynchronize( stop ) ;
float elapsedTime;//这个参数就是下面这个计算时间的函数用来输出时间的,必须是浮点型的好像
cudaEventElapsedTime(&elapsedTime,start, stop ) ;
printf( "Time to generate: %3.1f ms\n", elapsedTime );
cudaEventDestroy( start ) ;
cudaEventDestroy( stop ) ;//事件的内存在用完了也应该要释放,这也很重要
有关数学方面的计算我也没有深究,有时间再看,关键的是把常量内存搞清楚!