OpenCL 内核计时测量 0 秒或导致 SIGABRT

OpenCL Kernel timing measures 0 seconds or causes SIGABRT

本文关键字:SIGABRT 内核 测量 OpenCL      更新时间:2023-10-16

我在测量Arch Linux(Manjaro(上一个简单的OpenCL内核的时间时遇到了问题。OpenCL测量时间的方法给我一个0秒的时间或给出一个错误,这取决于条件。

我的问题

当在大NDRange上执行直通内核(基本上是out[i] = in[i];(时,CPU测量正确的执行时间,而OpenCL报告0。以下是控制台输出:

CPU: 1.27449 s
GPU: 0 s

直通.cpp(摘录(

#include <CL/cl2.hpp>
#include "../Timer.hpp"
// start timer
Timer t;
// enqueue blocking
cl::Event processingEvent;
cl_int err = device->_queue.enqueueNDRangeKernel(
passthrough, // kernel
cl::NullRange, // offset
cl::NDRange(bufferSize), // global range
{}, // local range
nullptr, // wait for events
&processingEvent // processing event
);
processingEvent.wait();
// measure time
double cpuUsec = t.deltaUsec();
double gpuUsec = Timer::deltaUsec(processingEvent);
// debug
cout << "CPU: " << cpuUsec / 1000000.0 << " sn";
cout << "GPU: " << gpuUsec / 1000000.0 << " sn";

计时器.cpp(摘录(

#include <chrono>
#include <ratio>
#include <CL/cl2.hpp>
Timer::Timer() {
from = high_resolution_clock::now();
}
double Timer::deltaUsec() {
return duration_cast<duration<double, std::ratio<1, 1000000>>>(high_resolution_clock::now() - from).count();
}
double Timer::deltaUsec(const cl::Event &event) {
return (double) Timer::deltaNsec(event) / 1000.0;
}
// main function for the timing
unsigned long Timer::deltaNsec(const cl::Event &event) {
auto end = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
auto start = event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
return end - start;
}

我试过什么

  1. 我仔细检查了输入值是否等于输出 - 因此内核实际上可以工作。
  2. 我停用了编译器优化 - 以防万一它们导致 GPU 对输入和输出值使用相同的缓冲区。
  3. 我添加了一些逻辑,因此代码确实需要更多时间来执行。
  4. 我在LLDB中检查了start,并在Timer::deltaNsec()end变量,使其不为0。它们不是,每次我检查时都会增加。
  5. #import cl2.hpp之前添加#define CL_HPP_ENABLE_EXCEPTIONS后,我收到以下SIGABRT错误:
terminate called after throwing an instance of 'cl::Error'
what():  clGetEventProfileInfo

LLDB向我暗示了Timer.cpp中的行auto end = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();,我认为这真的很令人困惑。

根据这个答案,我正确使用了计时器 - 是吗?


有关我的系统/环境的更多信息

使用的 OpenCL 驱动程序(摘自自定义 YAML(:

NVIDIA CUDA:
Vendor: NVIDIA Corporation
Version: OpenCL 1.2 CUDA 10.1.120
Devices:
GeForce GTX 1080 Ti:
Timer resolution (ns): 1000
Vendor: NVIDIA Corporation
Version: OpenCL 1.2 CUDA
Driver: 430.64

已安装的软件包

lib32-opencl-nvidia 1:430.40-1
opencl-headers 2:2.2.20170516-2

也许有人有类似的问题,可以提供帮助。

。我希望我提供了足够的信息 - 如果没有,请问!

Alan Birtles的回答帮助我找到了问题所在:

我用try-catch块包围了失败的代码并打印了错误代码,结果证明是-7: CL_PROFILING_INFO_NOT_AVAILABLE.

为了能够测量运行时,您需要在CommandQueue上启用分析,如下所示:

auto queue = cl::CommandQueue(
context,
device,
CL_QUEUE_PROFILING_ENABLE
);

谢谢艾伦!