gpt4 book ai didi

performance - 为什么在每个 clEnqueue 函数中都会调用 clGetPlatformInfo?

转载 作者:行者123 更新时间:2023-12-05 07:09:12 24 4
gpt4 key购买 nike

我们正在分析在主机和设备上的 NVidia GPU 上运行的 OpenCL 应用程序。我们惊讶地发现(基于 gperftools)主机花费 44% 的时间在 clGetPlatformInfo 上,该方法在我们自己的代码中只被调用一次。它由 clEnqueueCopyBuffer_hidclEnqueueWriteBuffer_hidclEnqueueNDRangeKernel_hid 调用(可能还有所有其他 clEnqueue 方法,但它们是在我们的代码中不太常用)。由于这占用了我们太多的主机时间,而且我们现在似乎受到主机速度的限制,我需要知道是否有办法消除这些额外的调用。

为什么每次 OpenCL 调用都会调用它? (大概是可以存储在上下文中的静态信息?)我们是否可能错误地初始化了我们的上下文?

编辑:有人要求我提供 MWE:

#include <CL/opencl.h>

#include <vector>
using namespace std;


int main ()
{
cl_uint numPlatforms;
clGetPlatformIDs (0, nullptr, &numPlatforms);

vector<cl_platform_id> platformIdArray (numPlatforms);
clGetPlatformIDs (numPlatforms, platformIdArray.data (), nullptr);

// Assume the NVidia GPU is the first platform
cl_platform_id platformId = platformIdArray[0];

cl_uint numDevices;
clGetDeviceIDs (platformId, CL_DEVICE_TYPE_GPU, 0, nullptr, &numDevices);

vector<cl_device_id> deviceArray (numDevices);
clGetDeviceIDs (platformId, CL_DEVICE_TYPE_GPU, numDevices, deviceArray.data (), nullptr);

// Assume the NVidia GPU is the first device
cl_device_id deviceId = deviceArray[0];

cl_context context = clCreateContext (
nullptr,
1,
&deviceId,
nullptr,
nullptr,
nullptr);

cl_command_queue commandQueue = clCreateCommandQueue (context, deviceId, {}, nullptr);

cl_mem mem = clCreateBuffer (context, CL_MEM_READ_WRITE, sizeof(cl_int),
nullptr, nullptr);

cl_int i = 0;

while (true)
{
clEnqueueWriteBuffer (
commandQueue,
mem,
CL_TRUE,
0,
sizeof (i),
&i,
0,
nullptr,
nullptr);

++i;
}
}

此 MWE 在几秒钟内生成以下配置文件。请注意,99% 的时间花在了 clGetPlatformInfo 上。 MWE Profile Results

最佳答案

尝试将 NULL 作为第一个参数传递给 clCreateContext。设备 ID 已被传递,因此可能不需要第一个参数,并且可能会导致对 clGetPlatformInfo 的这些额外调用。

要尝试的另一件事是链接非 Nvidia OpenCL 库。不需要使用 GPU 供应商 OpenCL 库,只要您正在使用的功能在此其他 OpenCL 库中实现,任何库都应该可以工作。使用 Nvidia 没有风险,因为就目前而言,最新支持的版本是 OpenCL 1.2,大多数(如果不是所有)供应商已经支持。因此,您可以尝试来自其他供应商 SDK(如 Intel 或 AMD)的 OpenCL 库。如果您使用的是 Ubuntu,则可以使用 ocl-icd-opencl-dev

======更新=========

尝试在创建上下文时指定平台:

const cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platformId, 0}; 

cl_context context = clCreateContext (
properties, // <-- here
1,
&deviceId,
nullptr,
nullptr,
nullptr);

可能是在创建上下文时未指定平台时,每次需要时都会查询它,但如果按上述方式指定,则不会。

关于performance - 为什么在每个 clEnqueue 函数中都会调用 clGetPlatformInfo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61663830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com