我正在尝试将MJPEG解码器的单线程串行代码转换为我想在GPU(NVIDIA Tesla k20c)上执行的OpenCL代码。
在将几个主要功能转换为内核之后,代码的执行时间从每帧约18 ms变为每帧惊人的400 ms。
我正在使用打开文件,读取文件,使用buffer和ndrange命令在GPU上执行代码并从CPU读取结果的标准方法。我觉得将mjpeg文件(属于数据类型FILE
)传输到GPU的内存将大大减少代码处理时的通信开销。
我引用了此链接,但建议仅适用于CUDA。该资源和NVIDIA的OpenCL指南介绍了固定内存的实用程序,但固定内存的使用仅限于内核参数和缓冲区命令。
我想将整个MJPEG文件(大小约为2.8 MB)传输到GPU的内存,但我一直在努力寻找实现这一目标的资源。
我可以安全地这样做吗?如果可以这样做,如何读取文件以执行MJPEG解码的各个步骤?
编辑:
我的GPU的详细信息如下:
DEVICE_NAME = Tesla K20c
DEVICE_VENDOR = NVIDIA Corporation
DEVICE_VERSION = OpenCL 1.2 CUDA
DRIVER_VERSION = 352.21
DEVICE_MAX_COMPUTE_UNITS = 13
DEVICE_MAX_CLOCK_FREQUENCY = 705
DEVICE_GLOBAL_MEM_SIZE = 5032706048
CL_DEVICE_ERROR_CORRECTION_SUPPORT: yes
CL_DEVICE_LOCAL_MEM_TYPE: local
CL_DEVICE_LOCAL_MEM_SIZE: 48 KByte
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: 64 KByte
CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_PROFILING_ENABLE
编辑:
Xirema给了我一个相当令人信服的答案。
如果在jpeg文件位于GPU上之后可以获得读取标记等的建议,我将不胜感激。还有其他巧妙的技巧可以更有效地读取标记吗?
没有什么能阻止您将图像的文字数据复制到主机内存中的缓冲区,然后再将其复制到GPU:
//HOST CODE
std::ifstream image_file("img.jpg", std::ios::binary);
std::vector<uint8_t> image_data;
image_file.seekg(0, std::ios_base::end);
size_t size = image_file.tellg();
image_data.resize(size);
image_file.seekg(0, std::ios_base::beg);
image_file.read(reinterpret_cast<char *>(image_data.data()), size);
cl_mem image_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size, image_data.data(), nullptr);
clSetKernelArg(kernel, 0, sizeof(cl_mem), &image_buffer);
clSetKernelArg(kernel, 1, sizeof(size_t), &size);
//DEVICE CODE
kernel void image_manipulation_function(global uchar * data, size_t data_size) {
//Go crazy.
//Seriously.
//(Mostly because you'd *have* to be crazy to think this is a good idea)
}
唯一悬而未决的问题是为什么您要这样做。大多数图像压缩算法都不太适合通常在GPU上解决的“令人尴尬的并行问题”,即使它们确实很好且高效地适应了多线程算法(大约2-16个线程)。除非您不了解某种不公开的实验研究,或者您的实际任务特别深奥,否则您不可能获得任何显着的速度提升。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句