Ray Tracing with CUDA on Windows 10
By: Joyce Chen
Tags: Cuda, Ray Tra, Computer Graphic, Computer, Cplusplus

I recently read and followed Peter Shirley’s Ray Tracing In One Weekend (http://in1weekend.blogspot.com/2016/01/ray-tracing-in-one-weekend.html). As I moved along with the book, the images were taking longer and longer to render. Eventually the following image, with 488 spheres and 10 samples per pixel took about 45 minutes to render on my PC. Having to wait so long for a still pretty noisy image bothers me. Luckily, there is a post by Roger Allen (https://devblogs.nvidia.com/accelerated-ray-tracing-cuda/) that discusses how to use CUDA in the same Ray Tracing project. I did my code modification mostly according to the repository posted in the linked post by Roger Allen. So the following blog post will mostly be about specific problems I encountered when making and running the project on Windows.

Regarding some tech specs, I’m using Visual Studio 15.9.5 and CUDA 10, and a GeForce 960m GPU.

Set up Project in Visual Studio 2017

Initially, I wanted to create a CUDA runtime application with Visual Studio because I wrote the non-CUDA version ray-tracer with VS. There was compatibility issues with VS 2017 and latest version of CUDA before; but this project builds and runs fine with the tech specs I mentioned in the beginning, with some small issues I will mention below.

The set up was rather straight-forward. I’ll skip the CUDA installation here. With CUDA 10 installed, we can just create a new CUDA runtime project.

You can find my code here: https://github.com/joycevk/SvampTracerCuda. However, there are a couple of issues. First, the compatibility issue between Visual Studio and CUDA 10 probably still persists. The following kernel launch code (and all kernel launch code) always shows an annoying expected an expression error. Just ignore it (if you can :P) and hit F5.

render_init <<<blocks, threads>>>(nx, ny, d_rand_state);

The second issue with VS is that the execution time is somehow significantly more than if I run the same code directly from command line. For the image that takes 23~ seconds to render, Visual Studio would probably take 2 to 3 minutes. If you know the reasons behind it, please comment and let me know 🙂

Not Using Visual Studio

For the reasons mentioned above, I actually recommend not using Visual Studio. Just use whatever editor you prefer and run the following commands to compile and run.

nvcc main.cu -o raytracer.exe

After this you will probably see some warnings like the following

ptxas warning : Stack size for entry function '_Z12create_worldPP7hitableS1_PP6cameraiiP17curandStateXORWOW' cannot be statically determined

Don’t worry about it. This is because there is recursion in our code, which we do and so the stack size cannot be determined at compile time. Just run the executable and we would get results similar to the following:

raytracer.exeRendering a 1200x800 image with 10 samples per pixel in 8x8 blocks. took 23.064 seconds.

Disable or extend WDDM TDR

If you don’t have a dedicated GPU, like I don’t, we have to extend or disable WDDM. For further information regarding what this is and what to do with it, I found this post to be useful: https://docs.nvidia.com/gameworks/content/developertools/desktop/timeout_detection_recovery.htm

We can do this through Nsignt Monitor. You probably need to run as administrator.

It’s NOT recommended to disable WDDM TDR completely. In this case I wasn’t sure how much time I need so I disable it just to run CUDA. I would also experiment with different delay time if you want to be safe.

Conclusion

The performance gain is such a relief. I have the following comparison:

============= 488 spheres 10 samples per pixel ================

Without CUDA : about 45 min

With CUDA : about 23 sec ============= 488 spheres 100 samples per pixel ================

Without CUDA : didn't have the patience to wait

With CUDA : about 130 sec

Granted, though, it might not be a fair comparison for the CPU because my Visual Studio runs on single CPU core. There are probably ways to increase the number of cores used with Visual Studio, which I didn’t have time to explore. So from my looking around online, the runtime without CUDA ranges from couple minutes to more than half an hour for different people. Regardless, I think the improvement can make us happy.

The process was not as smooth as I’d expected, mostly due to platform issues, but the result is so worth it. I’m excited to explore more with CUDA in the near future 😀