我最近使用constexprC++17 的函数编写了一个编译时光线追踪器。完整的源代码可以在这里看到。此问题的相关代码如下所示:
constexpr auto image = []() {
StaticImage<image_width, image_height> image;
Camera camera{Pointf{0.0f, 0.0f, 500.0f},
Vectorf{0.0f},
Vectorf{0.0f, 1.0f, 0.0f},
500.0f};
std::array<Shapes, 1> shapes_list{Sphere{Pointf{0.0f}, 150.0f}};
std::array<Materials, 1> materials_list{DefaultMaterial{}};
ShapeContainer<decltype(shapes_list)> shapes{std::move(shapes_list)};
MaterialContainer<decltype(materials_list)> materials{
std::move(materials_list)};
SphereScene scene;
scene.set_camera(camera);
Renderer::render(scene, image, shapes, materials);
return image;
}();
Run Code Online (Sandbox Code Playgroud)
其中每个这里示出的类(StaticImage,Camera,Shapes,Materials,ShapeContainer,MaterialContainer,和SphereScene)由完全constexpr的功能。Renderer::render也constexpr负责循环图像中的每个像素,将光线射入场景,并设置相应的颜色。
使用当前的设置和 512x512 的图像,在发布模式下使用 MSVC 16.9.2,编译器需要大约 35 分钟来完成生成图像。在此过程中,其内存使用量上升到最终使用近 64GB RAM 的程度。
所以,我的问题是:为什么编译时间和内存使用率这么高?
我的理论是编译时间的部分原因是调用堆栈的复杂性(即大量模板、CRTP 和深度),所以我尝试通过删除几个模板来稍微简化调用堆栈( …