问题标签 [amd-gcn]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
assembly - 是否可以在 AMD 的 GCN2+ GPU 上访问整个 64KB 的 Global Data Sharea (GDS)?
我正在尝试将 AMD RX 480 上的全局数据共享 (GDS) 用于我在 Linux 或 Windows 上的应用程序。尽管 GCN3 规范手册声明您可以通过为 m0 寄存器设置适当的值并在 GDS 位打开时发出数据共享指令来不受限制地访问 GDS,但根据我的经验,情况并非如此。更具体地说,您根本无法在 Windows 上访问 GDS,并且在 Linux 上一次只有 4KB 可用。有没有办法完全解除这种荒谬的限制?有关此问题的上下文,请参阅以下线程:
caching - 避免 GCN 设备上的 L1 缓存污染
我有一个将结果写入全局缓冲区的内核;这些结果永远不会读回内核(它们稍后由另一个内核处理)。
因此,如果我能提供帮助,我不希望这些数据位于 L1 缓存中。有没有办法确保它不被缓存?我需要 L1 用于另一个经常读取和写入的数组。这个数组大约 4kb,所以它应该保留在 L1 缓存中。
optimization - 在 AMD GCN OpenCL 上运行的优化内核是否一次只能处理约 1024 个字节?
我开始构建我的第一个严肃的 OpenCL 程序,我想确保我了解我的 AMD R9 290x 是如何设置的。(GCN 2.0 架构)。所以我只说我理解的,希望有人能告诉我我是对还是错?
在我看来,优化内核的一个主要问题是内存受限的性能。我真的不想在这里做“过早的”优化,但似乎至少考虑内存对于一般的 OpenCL 代码非常重要。(请参阅使用 GPU 进行排序:调查(Dmitri I. Arkhipov + 其他人))
根据AMD 的优化指南,每个向量单元每 4 个时钟可以运行 64 个工作项,每个工作项可以访问 256 个 32 位 vGPR。实际上,__private 数据(尝试)存储在 vGPR 中。
这导致了 1024 个用于 OpenCL 内核的“简单”访问寄存器。
看起来 LDS(又名 __local)可以用作 OpenCL 内核的高效存储,但它们的主要设计似乎是在工作组之间传递数据。由于计算单元的 64kb 在 4 个向量单元之间共享(理想情况下,每个单元至少有 64 个工作项的 1 个波前正在执行),最多可以为每个工作项分配 256 字节的 LDS 空间让系统尽可能“广泛”地运行。
因此,通过一些谨慎的 __local 和 __private 变量分配,每个工作项似乎有 1280 个“快速访问”字节可用。我猜 L1 缓存再授予 16kb(每个工作项只有 64 字节),但这需要一些小心的使用。此外,一级缓存还包含代码/指令,不能全部用于数据。“__constant”空间似乎是有效的 L1 空间,如果波前同步到相同的索引,可能会发生一些“多路复用”魔法。
上述计算均未考虑每个矢量单位的理论 10 波前(似乎共享 vGPR)。如果 R9 290x 实际上有 40 个波前同时执行,它们将仅使用 100 字节(每个工作项 25 个 vGPR)的快速存取存储器。
那么......这是对每个工作项在 R9 290x 等 GCN 设备中获得多少“快速”内存的正确理解吗?如果我们将 vGPR、L1 和 LDS 空间视为 R9 290x 可以使用的“快速”存储空间的总和,那么我们只考虑 1024 (vGPR) + 64 (L1) + 256 (LDS) 空间来工作和。
我确实意识到内核可以访问全局内存(在典型的 R9 290x 上约为 4GB,每个工作项大约为 1MB)。由于 GPU 上的全局内存仍然是高度并行化的 GDDR5 内存,我预计它会相当快,但它仍然比 L1 / vGPRs / LDS 空间慢一个数量级。因此,我希望最佳程序在不需要时尽量避免使用全局 RAM。
optimization - 向量化数据的 OpenCL (AMD GCN) 全局内存访问模式:跨步与连续
我将提高 OCL 内核性能,并想阐明内存事务如何工作以及哪种内存访问模式真正更好(以及为什么)。内核被输入了 8 个整数的向量,这些向量被定义为 array: int v[8],这意味着,在进行任何计算之前,必须将整个向量加载到 GPR 中。所以,我相信这段代码的瓶颈是初始数据加载。
首先,我考虑一些理论基础。
目标硬件是 Radeon RX 480/580,它具有 256 位 GDDR5 内存总线,在其上突发读/写事务具有 8 个字的粒度,因此,一个内存事务读取 2048 位或 256 字节。我相信 CL_DEVICE_MEM_BASE_ADDR_ALIGN 指的是:
因此,我的第一个问题是:128 字节缓存线的物理意义是什么?它是否保留了由单次突发读取但未真正请求的数据部分?如果我们请求 32 或 64 字节,剩下的会发生什么 - 因此,剩余的超过了缓存行的大小?(我想,它将被丢弃 - 那么,哪个部分:头部,尾部......?)
现在回到我的内核,我认为缓存在我的案例中没有发挥重要作用,因为一次突发读取 64 个整数 -> 一个内存事务理论上可以一次提供 8 个工作项,没有额外的数据要读取,并且内存是总是合并。
但是,我仍然可以使用两种不同的访问模式放置我的数据:
1) 连续的
(实际上表现为)
2) 交错
我希望在我的情况下连续会更快,因为如上所述,一个内存事务可以完全用数据填充 8 个工作项。但是,我不知道计算单元中的调度程序在物理上是如何工作的:是否需要为所有 SIMD 通道准备好所有数据,或者只需要 4 个并行 SIMD 元素的第一部分就足够了?尽管如此,我认为只要 CU 可以独立执行命令流,它就足够聪明地首先至少提供一个 CU 的数据。而在第二种情况下,我们需要执行 8 * global_size / 64 个事务来获得一个完整的向量。
所以,我的第二个问题:我的假设对吗?
现在,实践。
实际上,我将整个任务拆分为两个内核,因为其中一个部分的注册压力比另一部分小,因此可以使用更多的工作项。所以首先我使用了模式如何存储在内核之间转换的数据(使用 vload8/vstore8 或强制转换为 int8 给出相同的结果),结果有点奇怪:以连续方式读取数据的内核工作速度大约快 10%(两者都在CodeXL 和通过操作系统时间测量),但连续存储数据的内核执行速度出奇地慢。两个内核的总时间大致相同。在我看来,两者必须至少以相同的方式表现——要么更慢,要么更快,但这些相反的结果似乎无法解释。
我的第三个问题是:谁能解释这样的结果?还是我做错了什么?(或者完全错误?)
android - GCM 未在基于 ColorOS 的设备上接收
我有一个发送和接收 FCM 消息(Google Firebase 消息)的 android 应用程序。
它工作得很好,因为当我的应用程序不在前台或不使用它时我可以接收消息,因为我有一个正在运行的服务。
不幸的是,当我不在某些智能手机(如 OPPO、VIVO 或更可能在 ColorOS 上运行的)上运行应用程序或其背景时,它无法正常工作。
可能是什么问题?我们尝试过,但同样的情况也发生在 WhatsApp 上
以下是我的服务代码:
opencl - 如何在 AMD GCN 卡上为每个计算单元运行两个工作组
通常一个计算单元只能运行一个工作组。但是 AMD 的文档说,在同一个计算单元上可以运行多个波前。我怎样才能做到这一点?那是 OpenCL 的功能吗?或者我需要使用汇编指令?我想这样做是因为我的工作组大小是 20,我想每个计算单元运行 2 个工作组,这样每个组可以使用 32 KiB LDS(每个 CU 总共 64 KiB,每个波前最多可以使用 32KiB,所以我想要运行两个波前以使用全部 LDS)。
opencl - AMD GCN 卡上的 OpenCL 中的 uint2 操作是否比 ulong 更快?
哪个“+”计算更快?1) uint2 a, b, c; c = a + b; 2)乌龙a、b、c;c = a + b;
assembly - 如何在 AMD GCN 中读取和写入 Global Data Share?
我正在尝试在 AMD GPU 中使用 GDS,但我无法使其工作。我的 GPU 是 AMD RX580。
我使用了这个 OpenCL 内核:
用(CLRX)构建和拆卸。之后,我在 DS 指令中添加了 gds 标志并修改了 M0 寄存器。
所以我得到了这个 ASM 内核:
我在主机程序中用 0 填充 res 。预期的结果是res[0] == 64
。带有 LDS 的 OpenCL 内核就是这样工作的。但在 GDS 版本res[0] == 0
中。