Understanding the Efficiency of Ray Traversal on GPUs

Timo Aila     Samuli Laine

Abstract

We discuss the mapping of elementary ray tracing operations---acceleration structure traversal and primitive intersection---onto wide SIMD/SIMT machines. Our focus is on NVIDIA GPUs, but some of the observations should be valid for other wide machines as well. While several fast GPU tracing methods have been published, very little is actually understood about their performance. Nobody knows whether the methods are anywhere near the theoretically obtainable limits, and if not, what might be causing the discrepancy. We study this question by comparing the measurements against a simulator that tells the upper bound of performance for a given kernel. We observe that previously known methods are a factor of 1.5-2.5X off from theoretical optimum, and most of the gap is not explained by memory bandwidth, but rather by previously unidentified inefficiencies in hardware work distribution. We then propose a simple solution that significantly narrows the gap between simulation and measurement. This results in the fastest GPU ray tracer to date. We provide results for primary, ambient occlusion and diffuse interreflection rays.

Bibtex

@InProceedings{Aila2009hpg,
  author =    {Timo Aila and Samuli Laine},
  title =     {Understanding the Efficiency of Ray Traversal on GPUs},
  booktitle = {Proc. High-Performance Graphics 2009},
  pages =     {145--149},
  year =      {2009},
}

Downloads

PDF
Slides
Full implementation in Google code (reproduces the results below)

Acknowledgements

Marko Dabrovic (www.rna.hr) for the Sibenik cathedral model. University of Utah for the Fairy scene.

Additional results for newer GPUs

NEW: NVIDIA GTX680 (kernel=kepler_speculative_while_while)

Conference Fairy Sibenik San Miguel
ConferenceFairySibenikSan Miguel
Primary389.79227.31345.41136.95
AO428.92263.41369.07167.10
Diffuse198.25128.33161.1661.29
Unit: Mrays/sec.

Notes: On Kepler we fetch all node and triangle data through the texture cache, and L1 is used only for low-priority traffic (ray fetches, result writes) and local-mem traversal stacks. Kepler seems to like batched tex fetches to the point that it is beneficial to issue many fetches whose results have a low probability of being needed. Also, it seems beneficial to do even more speculative traversal work, we now postpone up to 2 leaf nodes. This time we tried to maximize the performance of diffuse (incoherent) rays.

The Kepler kernel can be found from here. We will update the Google code repository in May, but meanwhile plugging this kernel to the existing codebase should give at least approximately the quoted results.

NVIDIA GTX480 (kernel=fermi_speculative_while_while)

Conference Fairy Sibenik San Miguel
ConferenceFairySibenikSan Miguel
Primary253.49143.21223.8883.75
AO269.01156.64230.8294.57
Diffuse121.7470.0891.4233.89
Unit: Mrays/sec.