问题描述
考虑以下代码,它在 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 的行为是否相同?
- 除了总是从内核内部进行随机访问读取之外,还有其他解决方法吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)