У меня проблемы с измерением времени простого ядра OpenCL на Arch Linux (Манджаро). Средства OpenCL для измерения времени дают мне время 0 секунд или дают ошибку в зависимости от условий.
Моя проблема
При выполнении промежуточного ядра (в основном out[i] = in[i];
) на большом NDRange
ЦПУ измеряет правильное время выполнения, а OpenCL сообщает 0. Вот вывод консоли:
CPU: 1.27449 s
GPU: 0 s
passthrough. 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 << " s\n";
cout << "GPU: " << gpuUsec / 1000000.0 << " s\n";
Таймер. 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 использовать то же самое буфер для входных и выходных значений.
- Я добавил несколько логи c, поэтому для выполнения кода остро требуется больше времени.
- Я проверил в LLDB
start
и end
переменные в Timer::deltaNsec()
не равны 0. Они не увеличиваются и увеличиваются каждый раз, когда я проверяю. - После добавления
#define CL_HPP_ENABLE_EXCEPTIONS
перед e #import cl2.hpp
Я получил следующую ошибку SIGABRT:
terminate called after throwing an instance of 'cl::Error'
what(): clGetEventProfileInfo
LLDB намекнул мне на строку auto end = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
в Timer.cpp
, что, я думаю, действительно сбивает с толку.
Согласно на этот ответ Я правильно использовал таймер - не так ли?
Дополнительная информация о моей системе / среде
Использован драйвер 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
Возможно, у кого-то возникла подобная проблема, и она может помочь.
... и Я надеюсь, что предоставил достаточно информации - если нет, пожалуйста, спросите!