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 的行为是否相同?
  • 除了总是从内核内部进行随机访问读取之外,还有其他解决方法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)