OpenCL 内核计时测量 0 秒或导致 SIGABRT
OpenCL Kernel timing measures 0 seconds or causes SIGABRT
我在测量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;
}
我试过什么
- 我仔细检查了输入值是否等于输出 - 因此内核实际上可以工作。
- 我停用了编译器优化 - 以防万一它们导致 GPU 对输入和输出值使用相同的缓冲区。
- 我添加了一些逻辑,因此代码确实需要更多时间来执行。
- 我在LLDB中检查了
start
,并在Timer::deltaNsec()
中end
变量,使其不为0。它们不是,每次我检查时都会增加。 - 在
#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
);
谢谢艾伦!
相关文章:
- 如何在内核C++中使用1920x1080x16M图形或类似的16M颜色?(VGA)
- CUDA内核和数学函数的显式命名空间
- 码头化的C++应用程序是否向后兼容早期的内核版本
- C++内核出现Jupyter笔记本错误
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 内存围栏是否涉及内核
- 将 2D 推力::d evice_vector 复矩阵传递给 CUDA 内核函数
- 中止信号来自 C++ 中的中止(3) (SIGABRT)
- OpenCL 内核参数中的字符***?
- 具有可分离内核的 2D 模糊卷积
- 如何在Windows内核中获取文件大小
- 库达如何将字符**从内核复制到主机
- OpenCL 是否支持向量作为内核参数?
- pthread_spinlock是否会导致从用户空间切换到内核空间
- 为什么我在此代码中收到 SIGABRT 错误
- 如何在内核中添加包含库的路径?
- openCL 内核返回垃圾值,尽管没有错误
- OpenCL 内核计时测量 0 秒或导致 SIGABRT
- Visual Studio 如何在内核模式驱动程序项目中使用C++标准库?
- 分段错误(内核转储) C++面向对象编程