Vulkan hpp header 膨胀编译时间,寻找解决方法
Vulkan hpp header bloating compile times, looking for a workaround
我使用 clang 的 ftime-trace 来分析我程序的编译时间。事实证明,大约 90% 的时间都花在了解析 khronos 组提供的大量 vulkan.hpp header 上。
这反过来意味着,如果我尽量减少在 header 文件中包含此 header 并将其仅放在 cpp 文件中,我的编译时间应该会大大缩短。
但是我遇到了以下问题。
header 中有一些 object 是我到处都需要的。有一些错误代码枚举器、一些其他类型的枚举和一些 object 类型,例如
vk::Buffer
、vk::Image
等...
这些占总数的百分之一不到 header,但我不能不包括整个 header 就包括它们。我可以做些什么来仅挑选我实际使用的类型并避免在每次我需要我的代码与图像交互时包含整个 header?
有一些方法可以缓解您的问题。
vulkan_handles.hpp 存在
首先,现在有几个 header(以前没有,这在几乎每个 vulkan 调查中都是一个巨大的抱怨)。这并不能完全缓解您遇到的问题(header 仍然很大)但您不必包含 vulkan.hpp,它本身包含每个可用的 header,只是为了获得访问 vk::Image 和 vk::Buffer。现在可以在 vulkan_handles.hpp 中找到句柄(尽管它仍然有 13000 行长)。
前向声明
你说没有 类 因为 vulkan 的工作方式。假设,在很多情况下,您可以避免在 您的 header 文件中包含 Vulkan.hpp。
vk::Buffer、vk::Image 都可以前向声明,无需包含 header,只要您遵循 forward declaration rules
堆叠 PIMPLE 包装
你说你不能用类等等...那真的没有意义。 vk::Buffer 和 vk::Image 都是 类。假设您可以只为需要执行此操作的类型创建包装器 类,但是,为了消除开销,您必须事先为这些类型分配足够的 space。
现在在具有企业定义类型的大型企业库中,您通常不会这样做,因为类型的大小随时可能发生变化。然而,对于 vulkan.hpp,vulkan.hpp 正在使用的类型的大小和声明以及 它们的 包装器的大小确实定义得很好,不会改变,因为这会导致他们方面的其他不兼容性。
所以你可以假定这些类型的大小并创建类似的东西:
struct BufferWrapper{
// vulkan.hpp buffer only wraps buffer directly, does not inherit from anything, it's size should match it exactly
std::array<std::byte, sizeof(VkBuffer)> vk_data;
}
在 cpp 文件中....
BufferWrapper(...){
auto buffer_ptr = new vk_data vk::Buffer(...);
}
vk::Buffer* getBuffer(){
//technically undefined behavior IIRC,
return reinterpret_cast<vk::Buffer*>(&vk_data);
}
当然,因为它只包装缓冲区,你实际上可以直接使用 VkBuffer 并重新解释转换它。然后,您可以使用非显式转换运算符使缓冲区包装器自动转换为 vk::Buffer,使其在假设上非常无缝。
但是,如果不止几种类型,这将是一项 很多 的工作。如果你愿意投入那么多工作,那么你不妨...
使用 Vulkan.hpp/s 生成器仅生成 cpp/hpp 而不是仅生成 header
因此,如果您真的很认真地想要改变到目前为止的内容,不妨更改源代码。
首先,Vulkan hpp 不是直接编写的。 vulkan.hpp 是 生成的 。在 vulan-hpp 存储库中有 VulkanHppGenerator.hpp 和 .cpp。修改这些你让生成器生成源文件。您可以找到您需要的每个生成器的原型(即 generateHandle)。您可以假设更改输出以说明源文件。
但是这样做不在问题的范围内,我只是把它作为核选项提出来。
我使用 clang 的 ftime-trace 来分析我程序的编译时间。事实证明,大约 90% 的时间都花在了解析 khronos 组提供的大量 vulkan.hpp header 上。
这反过来意味着,如果我尽量减少在 header 文件中包含此 header 并将其仅放在 cpp 文件中,我的编译时间应该会大大缩短。
但是我遇到了以下问题。
header 中有一些 object 是我到处都需要的。有一些错误代码枚举器、一些其他类型的枚举和一些 object 类型,例如
vk::Buffer
、vk::Image
等...
这些占总数的百分之一不到 header,但我不能不包括整个 header 就包括它们。我可以做些什么来仅挑选我实际使用的类型并避免在每次我需要我的代码与图像交互时包含整个 header?
有一些方法可以缓解您的问题。
vulkan_handles.hpp 存在
首先,现在有几个 header(以前没有,这在几乎每个 vulkan 调查中都是一个巨大的抱怨)。这并不能完全缓解您遇到的问题(header 仍然很大)但您不必包含 vulkan.hpp,它本身包含每个可用的 header,只是为了获得访问 vk::Image 和 vk::Buffer。现在可以在 vulkan_handles.hpp 中找到句柄(尽管它仍然有 13000 行长)。
前向声明
你说没有 类 因为 vulkan 的工作方式。假设,在很多情况下,您可以避免在 您的 header 文件中包含 Vulkan.hpp。
vk::Buffer、vk::Image 都可以前向声明,无需包含 header,只要您遵循 forward declaration rules
堆叠 PIMPLE 包装
你说你不能用类等等...那真的没有意义。 vk::Buffer 和 vk::Image 都是 类。假设您可以只为需要执行此操作的类型创建包装器 类,但是,为了消除开销,您必须事先为这些类型分配足够的 space。
现在在具有企业定义类型的大型企业库中,您通常不会这样做,因为类型的大小随时可能发生变化。然而,对于 vulkan.hpp,vulkan.hpp 正在使用的类型的大小和声明以及 它们的 包装器的大小确实定义得很好,不会改变,因为这会导致他们方面的其他不兼容性。
所以你可以假定这些类型的大小并创建类似的东西:
struct BufferWrapper{
// vulkan.hpp buffer only wraps buffer directly, does not inherit from anything, it's size should match it exactly
std::array<std::byte, sizeof(VkBuffer)> vk_data;
}
在 cpp 文件中....
BufferWrapper(...){
auto buffer_ptr = new vk_data vk::Buffer(...);
}
vk::Buffer* getBuffer(){
//technically undefined behavior IIRC,
return reinterpret_cast<vk::Buffer*>(&vk_data);
}
当然,因为它只包装缓冲区,你实际上可以直接使用 VkBuffer 并重新解释转换它。然后,您可以使用非显式转换运算符使缓冲区包装器自动转换为 vk::Buffer,使其在假设上非常无缝。
但是,如果不止几种类型,这将是一项 很多 的工作。如果你愿意投入那么多工作,那么你不妨...
使用 Vulkan.hpp/s 生成器仅生成 cpp/hpp 而不是仅生成 header
因此,如果您真的很认真地想要改变到目前为止的内容,不妨更改源代码。
首先,Vulkan hpp 不是直接编写的。 vulkan.hpp 是 生成的 。在 vulan-hpp 存储库中有 VulkanHppGenerator.hpp 和 .cpp。修改这些你让生成器生成源文件。您可以找到您需要的每个生成器的原型(即 generateHandle)。您可以假设更改输出以说明源文件。
但是这样做不在问题的范围内,我只是把它作为核选项提出来。