我可以将 jpeg 或 mjpeg 文件从硬盘传输到 GPU 的内存吗?
Can I transfer a jpeg or mjpeg file from the hard drive to the GPU's memory?
我正在尝试将单线程 serial code for the MJPEG decoder 转换为我想在 GPU (NVIDIA Tesla k20c) 上执行的 OpenCL 代码。
将几个主要功能翻译成内核后,代码的执行时间从每帧 18 毫秒左右变成了糟糕的每帧 400 毫秒。
我正在使用打开文件、读取文件、使用缓冲区和 ndrange 命令在 GPU 上执行代码并从 CPU 读取结果的标准方法。 我觉得将mjpeg文件(数据类型FILE
)传输到GPU的内存中会大大减少代码处理时的通信开销。
我参考了 this link but the suggestions are only applicable to CUDA. This source and NVIDIA's OpenCL guide 解释固定内存的实用程序,但他们对固定内存的使用仅限于内核参数和缓冲区命令。
我想将整个 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 上解决的那种 "Embarassingly Parallel Problems",即使在它们确实很好地和高效地适应多线程算法(大约 2-16 个线程)的情况下也是如此。除非您了解某种不公开的实验研究,或者您的实际任务非常深奥,否则您不太可能获得任何显着的速度提升。
我正在尝试将单线程 serial code for the MJPEG decoder 转换为我想在 GPU (NVIDIA Tesla k20c) 上执行的 OpenCL 代码。
将几个主要功能翻译成内核后,代码的执行时间从每帧 18 毫秒左右变成了糟糕的每帧 400 毫秒。
我正在使用打开文件、读取文件、使用缓冲区和 ndrange 命令在 GPU 上执行代码并从 CPU 读取结果的标准方法。 我觉得将mjpeg文件(数据类型FILE
)传输到GPU的内存中会大大减少代码处理时的通信开销。
我参考了 this link but the suggestions are only applicable to CUDA. This source and NVIDIA's OpenCL guide 解释固定内存的实用程序,但他们对固定内存的使用仅限于内核参数和缓冲区命令。
我想将整个 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 上解决的那种 "Embarassingly Parallel Problems",即使在它们确实很好地和高效地适应多线程算法(大约 2-16 个线程)的情况下也是如此。除非您了解某种不公开的实验研究,或者您的实际任务非常深奥,否则您不太可能获得任何显着的速度提升。