为什么程序(全局)作用域变量必须是 __constant?

2024-03-25

我是 OpenCL 新手,对这个限制感到非常困惑。例如,如果我想写一个LCG,我必须使状态字可以修改为rand() and srand()。在 ANSI C 中,我将使用以下方法来做到这一点:

/* ANSI C */
static unsigned long _holdrand = 1; /* Global! */

unsigned long rand(){
    _holdrand = _holdrand * 214013L + 2531011L;
    return (_holdrand >> 16) & 0x7FFF; 
}
void srand( unsigned long seed ){
    _holdrand = seed;
}

但 OpenCL 限制所有全局范围变量__constant。我可以移动_holdrand进入函数作用域,并从该函数返回它的指针。

/* OpenCL C */
uint* holdrand(){
    __private static uint _holdrand = 1;
    return &_holdrand;
}

uint rand(){
    *holdrand() = *holdrand() * 214013L + 2531011L;
    return (*holdrand() >> 16) & 0x7FFF; 
}
void srand( uint seed ){
    *holdrand() = seed;
}

它工作正常,我不知道这是否是一个好的解决方案。这个限制毫无意义,我只是通过添加更多奇怪的代码来避免它。

__private uint _holdrand = 1;
/* It should be the same thing... Why this is not allowed? */

由于返回静态指针方式的行为与 ANSI C 中的全局范围变量方法完全相同,因此我无法理解该限制的含义。有人可以解释为什么吗?我错过了什么吗?我应该做什么才能使_holdrand在这个例子中可以在两个不同的函数中修改吗?


简而言之 - OpenCL 程序生命周期和内存布局与 C 程序不同。在 OpenCL 中,没有堆栈、堆等。常量内存(通常)非常快且片上内存量很少,IO 操作与寄存器操作相比具有相同的性能顺序。因此,它对工作项的写入操作可能有限制。

每个 NDRange(通常)中都有数千个工作项 (WI)。想象一下,如果 512 个线程正在读取/写入同一变量,您可以实现什么性能。这就是为什么你有 4 个地址空间:

  • __private对于每一个WI
  • __local对于工作组内的所有 WI
  • __global适用于 NDRange 内的所有 WI
  • __constant对于全局只读变量

If your rand() & srand()函数是 WI 特定的,您应该使用私有内存。另一种方法是在全局地址空间中包含所需的变量。但在这种情况下要非常小心竞争条件。

OpenCL 可以在各种各样的设备上运行,这就是为什么某些限制看起来太严格的原因。

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

为什么程序(全局)作用域变量必须是 __constant? 的相关文章

  • GPU 显存带宽理论与实际

    作为在 GPU 上运行的算法分析的一部分 我觉得我正在达到内存带宽的要求 我有几个复杂的内核执行一些复杂的操作 稀疏矩阵乘法 归约等 和一些非常简单的操作 当我计算每个内核读取 写入的总数据时 似乎所有 重要的 都达到了约 79GB s 的
  • OpenCL 产生错误的计算

    我一直尝试使用openCL做一些计算 但结果不正确 我输入了三个 float3 如下所示 300000 0 0 300000 300000 0 300000 300000 300000 进入这个内核 kernel void gravitat
  • OpenCL 编译器预处理定义?

    我正在 Snow Leopard 上开发 OpenCL 代码 并且了解 OpenCL 即时编译是由 Clang LLVM 完成的 是否使用了 C 预处理器 有没有办法使用编译器设置预处理定义 存在哪些定义 我希望代码知道它是为 CPU 还是
  • OpenCL clGetPlatformIDs 异常

    我使用此包安装附带的示例中的 HelloWorld 示例 AMD 套件 http developer amd com tools and sdks heterogeneous computing amd accelerated parall
  • Laravel 5.5:如何定义可在所有控制器中使用的全局变量?

    开发人员和编码人员您好 我的问题是如何定义一个全局变量 可以在 Laravel 中的所有控制器 我定义了一个变量 company in AppServiceProviders的启动方法 我在所有刀片视图中使用它 但我无法在控制器文件中使用它
  • 在 OpenCL 内核中动态创建本地数组

    我有一个 OpenCL 内核 需要将一个数组作为多个数组进行处理 其中每个子数组总和都保存在本地缓存数组中 例如 想象一下捕鸟数组 1 2 3 4 10 30 1 23 每个工作组都有一个数组 在示例中我们有 2 个工作组 每个工作项处理两
  • OpenCl 代码可以在一台机器上运行,但我在另一台机器上收到 CL_INVALID_KERNEL_ARGS

    我有以下代码 它在一台机器上运行良好 但是当我尝试在另一台具有更好显卡的机器上运行它时 我收到错误 global 0 512 global 1 512 local 0 16 local 1 16 ciErrNum clEnqueueNDRa
  • CUDA PTX 代码 %envreg<32> 特殊寄存器

    我尝试使用 CUDA 驱动程序 API 运行由 cl 内核生成的 PTX 汇编代码 我采取的步骤是这些 标准 opencl 程序 1 加载 cl内核 2 JIT编译 3 获取编译好的ptx代码并保存 到目前为止 一切都很好 我注意到 ptx
  • 多个 OpenCl 内核

    我只是想问 是否有人可以提醒我在相继使用几个简单内核时要注意什么 我可以用同样的吗CommandQueue 我可以跑几次吗clCreateProgramWithSource cl program与不同的cl program 我忘记了什么 T
  • 正确实施全局配置

    我的目标是在我正在开发的 C 游戏中拥有全局常量 以表示一些图形信息等 我当前的实现是将它们全部放在 h 中并将它们包含在各处 这是可行的 只是每次我更改设置时 都必须重新编译整个代码库 所以 我的下一个想法是将它们放入一些配置 txt 文
  • 使用 $& 全局变量的编程别名方法

    我正在尝试给一个使用 Ruby 特殊方法的方法起别名 返回最后一个正则表达式匹配 http jimneath org 2010 01 04 cryptic ruby global variables and their meanings h
  • 如何避免全局常量的“多重定义”错误?

    我正在使用 Windows API 编写 C 程序 每个主要函数都有自己的文件 并且有一个用于原型和包含内容的标头 Headers global constants pragma once define WIN32 LEAN AND MEA
  • 存储值以便在以后的函数中使用的最佳方法是什么?我听说全局变量很邪恶

    所以我使用的代码位于http jsfiddle net 8j947 10 http jsfiddle net 8j947 10 它为变量 isLive 返回 true 或 false 值 如何在稍后的函数中使用变量 onLive 我在以下位
  • 静态局部变量和静态全局变量有什么区别?

    C 入门 说 每个局部静态变量在第一次之前都会被初始化 执行通过对象的定义 本地静态数据是 函数结束时不会被销毁 当程序运行时它们被销毁 终止 局部静态变量与全局静态变量有什么不同吗 除了申报地点不同之外 还有什么不同呢 void foo
  • 请描述您在尽量减少使用全局变量方面的挣扎[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 OpenCL 或其他 GPGPU 框架在现代 x86 硬件上的 CPU 和 GPU 之间共享数据

    AMD Kaveri 的 hUMA 异构统一内存访问 和 Intel 第四代 CPU 证明了 CPU 和 GPU 硬件的不断统一 应该允许 CPU 和 GPU 之间进行无副本的数据共享 我想知道 最新的 OpenCL 或其他 GPGPU 框
  • 在不同的翻译单元中启动全局变量(涉及链接器)

    最近在复习C 这是我的问题 请参阅中的代码file1 cpp and file2 cpp 文件1 cpp int x1 1 int y1 x1 2 文件2 cpp include necessary headers extern int y
  • 杀死 OpenCL 内核

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

    我有一个看起来像这样的程序 offset Point new 100 200 def draw point pointNew offset point drawAbsolute point end draw Point new 3 4 指某
  • 反应。如何将 props 从 onClick 传递到 function

    我是反应新手 我正在尝试创建一个应用程序 在其中我可以单击按钮 并且函数将运行倒计时器 但是如果我从 onClick 传递道具来开始像这样的函数 onClick begin props subject 该函数将在我点击之前运行 如果我在不带

随机推荐