简体   繁体   English

OpenCL-C ++包装器-动态库中的上下文取消初始化会导致访问冲突

[英]OpenCL - C++ wrapper - Context deinitialization in dynamic library leads to access violation

I want to build a library (shared library on a windows system) which provides some default configurations (context,command queues, ...). 我想构建一个库(Windows系统上的共享库),该库提供一些默认配置(上下文,命令队列等)。 The problem is that I get an access violation when the application tries to exit. 问题是当应用程序尝试退出时出现访问冲突。 My first guess was that it might be a problem with my wrapper implementation but then I've built up a test case which uses the official C++ wrapper ( cl.hpp ). 我的第一个猜测是我的包装器实现可能存在问题,但是随后我建立了一个使用官方C ++包装器( cl.hpp )的cl.hpp

In the shared library 在共享库中

boost::optional<cl::Context> cpuContext;
void cpu() {
    cpuContext = cl::Context(CL_DEVICE_TYPE_CPU);
}

On the applcation side 在应用方面

int main(int argc, char** argv) {
    cpu();
}

So pretty simple stuff... 很简单的东西...

The interesting thing is that this happens only with the Intel runtime (can't test for Intel GPUs) but not with the runtime provided by Nvidia. 有趣的是,这仅发生在Intel运行时(无法测试Intel GPU),而不发生在Nvidia提供的运行时。 It also doesn't happen if the cpuContext variable is declared on the application side. 如果在应用程序端声明了cpuContext变量,也不会发生这种情况。

So my question is: 所以我的问题是:
Is this a bug in the Intel runtime or have I missed something and ran into undefined behavior? 这是Intel运行时中的错误,还是我错过了某些东西并遇到未定义的行为?

There's a potential for an very subtle issue if you try to release an OpenCL object from a DllMain. 如果尝试从DllMain释放OpenCL对象,则可能会出现非常细微的问题。 It can show the behavior you are seeing, but can be somewhat unpredictable or intermittent. 它可以显示您所看到的行为,但可能有些不可预测或断断续续。 First, a little background: 首先,有一点背景:

When you load OpenCL.dll, on most platforms you are loading a standardized Installable Client Driver (ICD) that is a shim between your code and the various implementations that might exist on your system. 当您加载OpenCL.dll时,在大多数平台上,您都在加载标准化的可安装客户端驱动程序(ICD),它是您的代码与系统上可能存在的各种实现之间的垫片。 You can read more about it here . 您可以在此处了解更多信息。 The ICD is a DLL that uses the Windows LoadLibrary call to load the DLLs provided by the OpenCL vendor (Intel, AMD, etc.). ICD是使用Windows LoadLibrary调用加载由OpenCL供应商(Intel,AMD等)提供的DLL的DLL。

Using LoadLibrary does not update Windows DLL dependency tracking structures. 使用LoadLibrary不会更新Windows DLL依赖关系跟踪结构。 So when the process shuts down, there is no way to know the order in which such DLLs will be unloaded. 因此,当进程关闭时,无法知道此类DLL的卸载顺序。 In this case, the vendor-supplied OpenCL DLLs could have already been unloaded by the time the destructor for your your global OpenCL context object is called. 在这种情况下,在调用全局OpenCL上下文对象的析构函数时,可能已经卸载了供应商提供的OpenCL DLL。 This has the potential to cause an access violation. 这有可能导致访问冲突。 You can read more about that here . 您可以在此处阅读更多有关此内容的信息

Given all of this, I would avoid designing a DLL that requires OpenCL functions be called in global object destructors or DllMain. 考虑到所有这些,我将避免设计一个需要在全局对象析构函数或DllMain中调用OpenCL函数的DLL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM