英特尔页面说:
因为一个应用程序中的多个 OpenMP 库会导致性能问题(线程过多),并且如果初始化多个副本,可能会导致正确性问题。
我们将我们的库与 libiomp5md.dll 链接并随其分发。我们的客户有一个问题,他使用了另一个使用 libiomp5mt.lib 的第三方库。使用最新的英特尔 MKL 重建该第 3 方应用程序并非易事。
我无法找到“如果初始化多个副本时的正确性问题”究竟是什么意思。您能否解释或举例说明什么是“副本”以及什么是“多个副本”?
“副本”是指运行时内存中的 OpenMP 库实例。只要所有代码都与 libiopm5md.dll动态链接,就不会有问题——您最终应该得到一个 OpenMP 运行时实例。但是,如果 DLL“A”与 OpenMP 库静态链接,而另一个 DLL“B”被动态链接,则最终可能会得到该库的两个副本,一个位于“A”内部,另一个为“B”而动态加载”。
正确性问题的一个例子是,threadprivate 变量曾经使用库中的哈希表实现,因此两个副本各有自己的哈希表。因此,给定一个线程私有变量“X”,一个线程可能会看到它在同一个线程中的 DLL“A”和“B”内具有不同的位置。
正确性问题的另一个例子是在 DLL 之间移动指针。一个 DLL 可以分配内存并将指针发送到另一个。如果另一个 DLL 尝试释放指针,结果将取决于 DLL 是否使用相同的内存分配器实例。
名称冲突可能会产生更微妙的问题。如果 OpenMP 运行时的两个副本在应用程序中工作,某些代码可能会意外调用错误的 OpenMP 实例。结果可能是静默错误执行。
实际上,如果在内存中有多个 OpenMP 运行时实例,精心编写的代码可能会很好地工作,但我们不能保证任何代码都能做到这一点。
安德烈