在Vulkan中,我们有两个需要加载dlopen/LoadLibrary的全局函数。他们是vkGetInstanceProcAddr和vkGetDeviceProcAddr。
我有一个gpu并安装了vulkan驱动程序。我应该在运行时或链接时加载库吗?我向vkGetDeviceProcAddr提供不同的逻辑设备(从同一个gpu创建)来查询相同的函数。他们都把相同的地址还给了我。我觉得再装子弹可能很浪费。
我的问题是这个想法是怎么来的?它是用于多实现还是多gpus?
我的加载程序功能当前如下所示:
class VulkanDevice
{
public:
VkDevice m_Device;
void LoadAllCoreFunctions();
void LoadExtension(const char *name);
void LoadExtensions(const char *postfix); // for example: "KHR"
PFN_vkCreateCommandBuffers vkCreateCommandBuffers;
// Then a lot of function pointers.....
}
int main() {
// After creating instance and creating device with vkCreateDevice
VulkanDevice vkd(device);
vkd.LoadAllCoreFunctions();
vkd.vkCreateCommandBuffers(vkd.m_Device, ....);
}
正如你所看到的,如果我有多个设备,重新加载将是相当浪费的.函数指针也需要很多内存..。
发布于 2016-08-15 12:15:32
在Vulkan中,我们有两个需要加载dlopen/LoadLibrary的全局函数。他们是vkGetInstanceProcAddr和vkGetDeviceProcAddr。
不对。只有vkGetInstanceProcAddr
。vkGetDeviceProcAddr
本身可以从vkGetInstanceProcAddr
加载。
我应该在运行时或链接时加载库吗?我向vkGetDeviceProcAddr提供不同的逻辑设备(从同一个gpu创建)来查询相同的函数。他们都把相同的地址还给了我。
VkInstance
从vkGetInstanceProcAddr
获取的命令被限制在与获取命令所用的完全相同的instance
上。
类似地,从vkGetDeviceProcAddr
获得的命令只能与用于获取它们的device
(类型为VkDevice)一起使用。
他们可能,而且经常是一样的,但你不可能事先知道,让它在每个平台/PC上这样工作。您可以只加载单个命令,以测试它是同一个指针,并推断其他的指针也是如此--但这将变得非常困难,没有任何合理的好处。
为了方便起见,请在链接时间与官方装载机联系,除非你有理由不这样做.
我觉得再装子弹可能很浪费。
除非您计划使用数百万GPU不断地连接和断开连接,否则不要担心它并正确加载命令。这是一个很小(或很少)的-time成本,这将很快摊销在所有的渲染,你无疑会做它之后。
也没有“重新装填”。新指针可以与旧指针和平共处。在C++中,您可能会使实例或设备的那些成员函数.
我的问题是这个想法是怎么来的?它是用于多实现还是多gpus?
是的,算是吧。
您肯定会看到,如果您有两个GPU(来自不同供应商的GPU),具有不同的驱动程序文件(通常是一些*.dll或其他平台上的类似文件),那么必须以某种方式选择指向正确文件的指针。
vkGetInstanceProcAddr
解决了这个问题,因此它为您提供指向另一个函数的指针,该函数选择并调用正确的指针。(“一切都可以通过另一个层次的间接解决”,对吧?)静态加载Khronos/官方/LunargSDK加载程序可能会做类似的事情。
对于vkGetDeviceProcAddr
,您只需给出确切的设备,然后它将为您提供一个指向特定GPU驱动程序的直接函数指针。
对于实例也可能发生同样的情况(加载程序只能导出vkGetInstanceProcAddr
,rest可以在其他地方)。尽管通常(就像Loader的情况一样),为了方便起见,它会导出所有实例级甚至间接设备级函数指针。
正如你所看到的,如果我有多个设备,重新加载将是相当浪费的.函数指针也需要很多内存..。
没有像前面说的那样浪费那么多CPU时间。
如果您没有这几个指针的kB,那么无论如何您可能都无法执行可行的基于Vulkan的应用程序。您只能加载实际使用的命令,但我不认为这种过早优化的原因。你有一些特殊的HW,需要这样的绝望措施或做一个64K演示?
发布于 2016-08-15 02:00:33
“实例函数指针”和“设备函数指针”之间的区别是针对那些想要更快的函数调用性能的人。
您可以只使用vkGetInstanceProcAddr
就可以使用Vulkan。此函数将检索所有Vulkan函数的函数指针。这些函数指针将使用存储在您传递的各种Vulkan对象中的调度信息,以确定您正在与哪个设备交谈。这些指针可用于任何实例、设备或依赖于设备的对象.
从vkGetDeviceProcAddr
获得的指针知道它们与特定的设备一起工作。他们不需要使用调度逻辑来调用该设备。所以他们的水平稍低。缺点是,您只能在特定的VkDevice
或设备派生对象中使用它们。
调度开销可能不够大,不值得大多数人费心。然而,如果你真的关心这些事情,你可以选择避免它。
如果我有多台设备的话,重新装载会很浪费.函数指针也需要很多内存..。
不管您是否查询它们的指针,这些函数都是存在的;因此,获取它们的指针只占用用于存储指向它们的指针的内存。Vulkan的API包含大约140个函数。每个函数指针为8字节,即1120字节,略高于1KB。
至于装货的时间..。如果加载140个函数指针的时间超过几微秒,我会感到震惊。你在刚开始的时候做过一次。
https://stackoverflow.com/questions/38948159
复制相似问题