在 OpenCL 内核中实现小型查找表的最佳方法是什么

2024-01-02

在我的内核中,需要对一个小查找表(只有 8 个 32 位整数)进行大量随机访问。每个内核都有一个唯一的查找表。下面是内核的简化版本,用于说明如何使用查找表。

__kernel void some_kernel(  
    __global uint* global_table,
    __global uint* X,
    __global uint* Y) {

    size_t gsi = get_global_size(0);
    size_t gid = get_global_id(0);

    __private uint LUT[8]; // 8 words of of global_table is copied to LUT

    // Y is assigned a value from the lookup table based on the current value of X
    for (size_t i = 0; i < n; i++) {
        Y[i*gsi+gid] = LUT[X[i*gsi+gid]];
    }   
}

由于尺寸较小,我通过将表保留在 __private 内存空间中来获得最佳性能。然而,由于访问查找表的随机性,仍然对性能造成很大影响。删除查找表代码后(例如,用简单的算术运算代替),尽管内核会提供错误的答案,但性能会提高 3 倍以上。

有没有更好的办法?我是否忽略了一些 OpenCL 功能,该功能可以为非常小的内存块提供高效的随机访问?是否有使用向量类型的有效解决方案?

[编辑] 请注意,X 的最大值为 7,但 Y 的最大值为 2^32-1。换句话说,查找表的所有位都被使用,因此它不能被打包成更小的表示形式。


我能想到的最快的解决方案是首先不使用数组:而是使用单个变量并使用某种访问函数来访问它们,就像它们是数组一样。 IIRC(至少对于 AMD 编译器来说是这样,但我很确定对于 NVidia 来说也是如此):一般来说,数组总是存储在内存中,而标量则存储在内存中may被存储在寄存器中。 (但我对这个问题有点模糊——我可能是错的!)

即使您需要一个巨大的 switch 语句:

uint4 arr0123, arr4567;
uint getLUT(int x) {
    switch (x) {
    case 0: return arr0123.r0;
    case 1: return arr0123.r1;
    case 2: return arr0123.r2;
    case 3: return arr0123.r3;
    case 4: return arr4567.r0;
    case 5: return arr4567.r1;
    case 6: return arr4567.r2;
    case 7: default: return arr4567.r3;
    }
}

...与 __private 数组相比,您可能仍然在性能方面领先,因为假设 arr 变量全部适合寄存器,则纯粹是 ALU 绑定的。 (当然,假设您有足够的备用寄存器用于 arr 变量。)

请注意,某些 OpenCL 目标甚至不have私有内存,您在那里声明的任何内容都会进入 __global。使用寄存器存储是一个更大的胜利。

当然,这种 LUT 方法的初始化速度可能较慢,因为您需要至少两次单独的内存读取来从全局内存复制 LUT 数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 OpenCL 内核中实现小型查找表的最佳方法是什么 的相关文章

  • 什么样的工作受益于 OpenCL

    首先 我很清楚 OpenCL 并没有神奇地让一切变得更快 我很清楚 OpenCL 有局限性 现在回答我的问题 我习惯使用编程进行不同的科学计算 我处理的一些事情在计算的复杂性和数量方面非常激烈 所以我想知道 也许我可以使用 OpenCL 来
  • OpenCL 中的最佳本地/全局工作规模

    我想知道如何在 OpenCL 中为不同设备选择最佳的本地和全局工作大小 AMD NVIDIA INTEL GPU 有什么通用规则吗 我是否应该分析设备的物理构建 多处理器数量 多处理器中的流处理器数量等 这取决于算法 实现吗 因为我看到一些
  • OpenGL-OpenCL 互操作传输时间 + 位图纹理

    两部分问题 我正在开展一个学校项目 使用生命游戏作为实验 gpgpu 的工具 我使用 OpenCL 和 OpenGL 进行实时可视化 目标是让这个东西尽可能大 更快 经过分析 我发现帧时间主要由 CL 获取和释放 GL 缓冲区决定 并且时间
  • 并行化 std::nth_element 和 std::partition

    我正在移植使用的 C 代码std nth element and std partition到 OpenCL nth element http www cplusplus com reference algorithm nth elemen
  • 工作组之间的 OpenCL 同步

    是否可以同步 OpenCL 工作组 例如 我有 100 个工作组 每个工作组只有一个项目 不要问我为什么 这是一个例子 我需要对每个工作项设置障碍 以确保所有工作组都会在这 100 个工作组中的每个工作项达到此障碍点后继续 不 你不能 您可
  • OpenCL 本地内存大小和计算单元数量

    每个 GPU 设备 AMD NVidea 或任何其他 都分为多个计算单元 多处理器 每个计算单元都有固定数量的内核 顶点着色器 流处理器 所以 一个人有 Compute Units x VertexShaders compute unit
  • 如何在 OpenCL 中验证波前/扭曲大小?

    我使用的是 AMD Radeon HD 7700 GPU 我想使用以下内核来验证波前尺寸是否为 64 kernel void kernel test warpsize global T dataSet uint size size t id
  • OpenCL clBuildProgram 缓存源代码,如果 #include 源代码发生更改,则不会重新编译

    我用opencl实现了一个项目 我有一个包含内核函数的文件 内核使用的函数包含在单独的头文件中 但是当我更改包含的文件时 有时会应用更改 有时则不会 这让我很困惑应用程序是否有错误 我检查了 stackoverflow 中的其他帖子 发现
  • OpenCL 双精度与 CPU 双精度不同

    我正在 Linux 中使用 GeForce GT 610 卡进行 OpenCL 编程 我的CPU和GPU双精度结果不一致 我可以在这里发布部分代码 但我首先想知道是否有其他人遇到过这个问题 当我运行多次迭代的循环时 GPU 和 CPU 双精
  • OpenCL:头文件的附加目录

    OpenCL 规范中写道5 6 3 构建选项 5 6 3 1 预处理器选项 I dir Add the directory dir to the list of directories to be searched for header f
  • opencl支持布尔变量吗?

    openCL 支持布尔变量吗 我目前正在使用 JOCL java 编写我的 openCL 调用代码 但我没有看到任何有关布尔值的信息 tl dr 是的 但是你应该在内核函数签名中避免它 是的 但a的大小bool is not定义的 因此 它
  • 如何消除 opencl 代码中的 CL_INVALID_PLATFORM 错误?

    使用 OpenCL 进行简单的矩阵乘法 Multiply two matrices A B C include
  • 为什么程序(全局)作用域变量必须是 __constant?

    我是 OpenCL 新手 对这个限制感到非常困惑 例如 如果我想写一个LCG 我必须使状态字可以修改为rand and srand 在 ANSI C 中 我将使用以下方法来做到这一点 ANSI C static unsigned long
  • OpenCL 在调用 clGetPlatformIDs 时崩溃

    我是 OpenCL 新手 在配备 Intel R HD Graphics 4000 运行 Windows 7 的 Core i5 计算机上工作 我安装了支持 OpenCL 的最新 Intel 驱动程序 GpuCapsViewer 确认我有
  • 空的 openCL 程序抛出弃用警告

    我下载了 AMD APP 3 0 SDK 一旦包含 include
  • 杀死 OpenCL 内核

    有没有办法通过 OpenCL API 终止正在运行的 OpenCL 内核 我在规范中没有找到任何内容 我能想到的唯一解决方案是 1 定期检查内核中主机希望内核停止时写入的标志 或 2 在单独的进程中运行内核并终止整个进程 我认为这两个都不是
  • 如何在 C 中将向量参数传递给 OpenCL 内核?

    我在将向量类型 uint8 参数从 C 中的主机代码传递到 OpenCL 内核函数时遇到问题 在主机中 我将数据存储在数组中 cl uint dataArr 8 1 2 3 4 5 6 7 8 我的真实数据不仅仅是 1 8 这只是为了便于解
  • OpenCL 与 OpenMP 性能对比 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否有研究比较 OpenCL 与 OpenMP 的性能 具体来说 我对使用 OpenCL 启动线程的开销成本感兴趣 例如 如果将域分解
  • 如何在 Emgu CV 项目中利用 OpenCL

    我是使用 Emgu CV 的新手 并开始创建小型示例项目 例如面部检测 眼睛检测等 如果我可以利用 OpenCL 来加速使用 GPU 的过程 那就太好了 否则 当我降低scaleFactor时 它会导致大量的CPU利用率 我怎样才能做到这一
  • 是否可以在 OpenCL 中并行运行求和计算?

    我是 OpenCL 的新手 不过 我了解 C C 基础知识和 OOP 我的问题如下 是否可以以某种方式并行运行求和计算任务 理论上可能吗 下面我将描述我尝试做的事情 任务例如是 double values new double 1000 l

随机推荐