如何解决OpenCL“非阻塞”读取的成本高于预期
考虑以下代码,它在 1 到 100000 次“非阻塞”随机访问缓冲区读取之间排队并测量时间:
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <vector>
#include <iostream>
#include <chrono>
#include <stdio.h>
static const int size = 100000;
int host_buf[size];
int main() {
cl::Context ctx(CL_DEVICE_TYPE_DEFAULT,nullptr,nullptr);
std::vector<cl::Device> devices;
ctx.getInfo(CL_CONTEXT_DEVICES,&devices);
printf("Using OpenCL devices: \n");
for (auto &dev : devices) {
std::string dev_name = dev.getInfo<CL_DEVICE_NAME>();
printf(" %s\n",dev_name.c_str());
}
cl::CommandQueue queue(ctx);
cl::Buffer gpu_buf(ctx,CL_MEM_READ_WRITE,sizeof(int) * size,nullptr);
std::vector<int> values(size);
// Warmup
queue.enqueueReadBuffer(gpu_buf,false,sizeof(int),&(host_buf[0]));
queue.finish();
// Run from 1 to 100000 sized chunks
for (int k = 1; k <= size; k *= 10) {
auto cstart = std::chrono::high_resolution_clock::now();
for (int j = 0; j < k; j++)
queue.enqueueReadBuffer(gpu_buf,sizeof(int) * (j * (size / k)),&(host_buf[j]));
queue.finish();
auto cend = std::chrono::high_resolution_clock::now();
double time = std::chrono::duration<double>(cend - cstart).count() * 1000000.0;
printf("%8d: %8.02f us\n",k,time);
}
return 0;
}
一如既往,有一些随机变化,但对我来说典型的输出是这样的:
1: 10.03 us
10: 107.93 us
100: 794.54 us
1000: 8301.35 us
10000: 83741.06 us
100000: 981607.26 us
虽然我确实预计单次读取的延迟相对较高,但考虑到需要 PCIe 往返,我对将后续读取添加到队列中的高成本感到惊讶 - 好像真的没有“队列” ' 但每次读取都会增加完整的延迟损失。这是在带有 Linux 和驱动程序版本 455.45.01 的 GTX 960 上。
- 这是预期的行为吗?
- 其他 GPU 的行为是否相同?
- 除了总是从内核内部进行随机访问读取之外,还有其他解决方法吗?
解决方法
您正在使用单个有序命令队列。因此,所有排队读取都由硬件/驱动程序按顺序执行。
“非阻塞”方面仅仅意味着调用本身是异步的,并且不会在 GPU 工作时阻塞您的主机代码。
在您的代码中,您使用 clFinish
阻塞直到所有读取完成。
所以是的,这是预期的行为。您将为每次 DMA 传输支付全时罚款。
只要您创建一个有序的命令队列(默认),其他 GPU 的行为就会相同。
如果您的硬件/驱动程序支持乱序队列,您可以使用它们来潜在地重叠 DMA 传输。或者,您可以使用多个有序队列。但性能当然取决于硬件和驱动程序。
使用多个队列/乱序队列更高级一些。您应该确保正确利用事件以避免竞争条件或导致未定义的行为。
为了减少与 GPU 主机 DMA 传输相关的延迟,建议您使用固定主机缓冲区而不是 std::vector
。固定主机缓冲区通常通过带有 clCreateBuffer
标志的 CL_MEM_ALLOC_HOST_PTR
创建。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。