赞
踩
问题背景与相关知识
在深度学习流行的当下,深度学习的框架大多是基于Python的实现,抑或是提供了Python的接口。而为了保证性能,底层计算通常是使用C/C++实现的。对于C/C++项目,其链接方式主要可以分为以下两种:静态链接方式 (Static linking)
静态链接即在链接时即确定程序会包含哪些模块。由于在链接时已经确定了所有包含的模块,那么会直接将这些模块打包,生成一个新的可执行文件或者静态链接库文件。
因而这种方法具有如下特点:分发简单。因为其不存在运行时才能解决的依赖。
由于无法事先知道用户会使用其中的哪些模块以及哪些函数,因而产生的静态链接库会比较大。
动态链接方式 (Dynamic linking)
动态链接方式即在链接时仅确定包含模块的名称、以及其中所用到的函数,生成一个可执行程序或是动态链接库(DLL)。而在运行时,根据这些信息来寻找相应的模块进行加载。
这种方法的特点有:由于在运行时才加载对应的模块,因而可以将模块进行替换。
由于所依赖的模块没有被包含进来,因此生成的动态链接库不会太大。
由于动态的加载,因而会受用户环境的影响,因而在分发时有可能产生问题。
在目前 Windows 的大多数深度框架下,大多采用动态链接方式。其原因在于深度学习框架中需要包含许多 OP 的实现,这些实现需要覆盖多种指令集、多个 CUDA 架构,因而生成的目标文件会比较大。而64位 Windows 下对于单个模块要求大小不能超过4GB。
某些模块不提供静态链接库,比如 cuDNN 等。
在动态链接方式的第三个特点中,我们说到了分发时可能会产生问题。这类问题通常被称为"DLL Hell"。可以考虑下面一个场景:
程序 P1 依赖于 库 L 的一个版本 L1。用户为了能使用 P1,将 L1 放在系统目录中。而某一天,用户又需要使用程序 P2,而 P2 则依赖于 库 L 的另一个版本 L2。假设 L1 和 L2 是无法互相兼容的,那么用户就无法同时使用 P1 和 P2。
为了解决这样一种问题,有如下的一些解决方法每个程序自带一份动态链接库的局部拷贝。即 P1 分发时带上 L1,而 P2 分发时带上 L2,这样两者就不会互相干扰。但是很明显,这种方式会导致一个动态链接库的多次拷贝,造成空间的浪费。
很明显 L1 和 L2 会互相冲突,是因为两者的名称一样,那么对于无法互相兼容的包,直接取不同的文件名就完了。这正是
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。