如何解决将多个设备传递给一个上下文,是否意味着内核将分发到两个设备?
我一直在编写一些基本的 OpenCL 程序并在单个设备上运行它们。我一直在对代码的性能进行计时,以了解每个程序的性能。
我一直在考虑让我的内核同时在 GPU 设备和 CPU 设备平台上运行。 cl::context 构造函数可以传递一个 std::vector 设备,以初始化具有多个设备的上下文。我的系统只有一个 GPU 和一个 CPU。
为了将内核分发到多个设备,您是否只需要使用可用设备向量构建上下文?当我使用 2 个设备构建上下文时,我注意到性能显着提高,但这似乎太简单了。
有一个 DeviceCommandQueue 对象,也许我应该使用它为每个设备显式创建一个队列?
解决方法
我对我的系统进行了一些测试。事实上,你可以这样做:
foopassfoopass
我发现如果两个设备来自不同的平台(例如一个 Nvidia GPU 和一个 Intel GPU),using namespace cl;
Context context({ devices[0],devices[1] });
queue = CommandQueue(context); // queue to push commands for the device,however do not specify which device,just hand over the context
Program::Sources source;
string kernel_code = get_opencl_code();
source.push_back({ kernel_code.c_str(),kernel_code.length() });
Program program(context,source);
program.build("-cl-fast-relaxed-math -w");
将在运行时抛出读取访问冲突错误或 clCreateContext
将在运行时失败。但是,如果两个设备来自同一平台,则代码将编译并运行;但它不会在两个设备上运行。我使用 Intel i7-8700K CPU 及其集成的 Intel UHD 630 GPU 进行了测试,无论创建 program.build
的向量中设备的顺序如何,在这种情况下,代码将始终在 CPU 上执行.我检查了 Windows 任务管理器以及内核执行时间测量的结果(执行时间特定于每个设备)。
您还可以使用任务管理器等工具监控设备使用情况,以查看实际运行的是哪个设备。如果您的系统与我观察到的有任何不同,请告诉我。
通常,跨多个设备的并行化不是通过将设备向量交给上下文来完成,而是为每个设备提供一个专用的 context
和 context
并明确处理哪个内核在哪个队列上执行。这使您可以完全控制内存传输和执行顺序/同步点。
在传入设备向量时,我发现性能有所提高。我下载了一个 CPU/GPU 分析器来实际检查我在运行代码时 GPU 和 CPU 的活动,而且我似乎在两个设备上都看到了活动。 CPU 注册了大约 95-100% 的活动,而 GPU 达到了 30-40%,因此 OpenCL 必须在两个设备之间拆分内核。我的电脑有一个带有集成 GPU 的 CPU,这可能是内核在设备之间共享的原因,因为它不像它有一个 CPU 和一个完全独立的 GPU,它们连接在同一个组件上。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。