问题标签 [gpu-shared-memory]

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.

0 投票
3 回答
1747 浏览

cuda - 如果为整个网格分配的共享内存量超过 48kB,则内核启动失败

我正在研究需要大量共享内存的 N 体问题。

基本上,有N独立的任务,每个任务使用 4 个双精度变量,即 32 个字节。单个任务由一个线程执行。

为了快速起见,我一直在为这些变量使用共享内存(假设寄存器也被线程使用)。由于N在编译时不知道任务的数量,因此共享内存是动态分配的。

  • 网格的维度和共享内存的计算取决于N块大小:

    /li>
  • 然后使用这 3 个变量启动内核。

    /li>

对于 small N,这可以正常工作,并且内核执行时不会出错。

但是如果超过N = 1500,内核启动失败(以下消息多次出现):

据我了解,这是由于试图写入超出已分配共享内存的界限。当在内核中将全局内存复制到共享内存中时,就会发生这种情况:

此错误仅在 时发生,因此当共享内存N > 1500总量超过48kB ( ) 时。 无论网格和块大小如何,此限制都是相同的。1500 * 4 * sizeof(double) = 1500 * 32 = 48000

如果我正确理解了 CUDA 的工作原理,那么网格使用的共享内存的累积量不限于48kB,这只是单个线程块可以使用的共享内存的限制。

这个错误对我来说毫无意义,因为累积的共享内存量只会影响流式多处理器之间的网格调度方式(此外,GPU 设备有 15 个 SM 可供使用)。

0 投票
1 回答
59 浏览

parallel-processing - OpenCL 中针对迭代问题的最佳通用计算实践是什么?

当我们有一个程序需要对大型数据集进行大量操作并且对每个数据元素的操作是独立的时,OpenCL 可能是使其更快的不错选择之一。我有一个类似以下的程序:

在这里,function1 应用于 BigData 上的每个元素,并生成另外两个大数据集 (X,Y)。然后 function2 和 function3 分别对这些 X、Y 数据上的每个元素分别应用操作。

由于所有函数的操作都独立应用于数据集的每个元素,因此使用 GPU 可能会使其更快。所以我想出了以下几点:

然而,这段代码所涉及的开销对我来说似乎很重要(我已经实现了一个测试程序并在 GPU 上运行)。如果内核有某种同步,它可能会以更慢的速度结束。

我也相信工作流程很常见。那么使用 OpenCL 来加速这样的程序的最佳实践是什么?

0 投票
1 回答
175 浏览

c++ - 内核启动指定流,但使用默认共享内存大小

我需要为 CUDA 中的内核启动指定流。内核使用一些共享内存,其大小在内核代码中定义。

但是,共享内存大小参数位于内核启动表达式中的流参数之前。那么如何告诉 CUDA 使用内核代码指定的共享内存大小而忽略启动代码中的内容呢?

显然,我想避免代码重复(cBlockSize/16)*sizeof(uint32_t)再次放在那里。实际上,表达式更复杂。

0 投票
1 回答
243 浏览

cuda - 我可以从内核中获取分配的动态共享内存的数量吗?

在主机端,我可以保存我打算用来启动内核的动态共享内存量,并使用它。我什至可以将它作为参数传递给内核。但是 - 有没有办法直接从设备代码中获取它,而无需主机端的帮助?也就是说,内核的代码在运行时确定它有多少可用的动态共享内存?

0 投票
1 回答
1199 浏览

cuda - CUDA 非法内存访问,共享内存可能“不足”

我有一个简单的 CUDA 内核,可以通过基本归约来进行矢量累加。我将其扩展为能够通过将其拆分为多个块来处理更大的数据。但是,我关于分配适当数量的共享内存以供内核使用的假设因非法内存访问而失败。当我增加这个限制时它就消失了,但我想知道为什么。这是我正在谈论的代码:

核心内核:

这是调用者:

我在 GPU 上使用包含 1152 个元素的样本集尝试了此代码,配置如下:类型:Quadro 600 MaxThreadsPerBlock:1024 MaxSharedMemory:48KB

输出:

怀疑我的“临时”共享内存导致非法内存访问,我在以下行中任意将共享内存增加了两倍:

我的内核开始正常工作了!

我不明白的是 - 为什么我必须提供这个额外的共享内存来让我的问题消失(暂时)。

作为检查这个幻数的进一步实验,我用一个更大的数据集运行了我的代码,数据集有 6912 个点。这一次,即使是 2X 或 4X 也没有用。

但是当我将共享内存大小增加 8 倍时,问题又消失了。

当然,我不能为越来越大的数据集随意选择这个比例因子,因为我很快就会用完 48KB 的共享内存限制。所以我想知道解决我的问题的合法方法。

0 投票
1 回答
631 浏览

c++ - CUDA中可变矩阵大小的矩阵乘法和共享内存的使用

我想在 CUDA 中实现一个简单的矩阵乘法。矩阵的维度是在运行时确定的,我还想使用共享内存来提高性能。我已经实现了这样的功能,但是每次运行它时,都会出现此错误:

我也不确定是否可以使用 malloc 分配共享内存。但是,如果我想使用这样的东西

编译器抱怨必须在运行时知道 tile_width ......

我已经尝试了我能想到的一切,也尝试了各种建议,但没有一个奏效。这是函数(完整的工作文件可以在这里找到):

基本布局应该可以工作,因为我还实现了一个没有共享内存的版本,它工作得很好。不带共享内存的函数如下:

如果有任何信息丢失,我会立即提供。

0 投票
1 回答
1608 浏览

cuda - CUDA 在哪里声明共享内存分配的常量

我正在为 1024 个矩阵运行适应度函数,每个矩阵都有自己的块并且大小相同。每个块都有n*n线程(矩阵的维度)并且需要n*n共享内存,以便我可以轻松地进行求和。但是,所有矩阵的维度n在运行前都是可变的(即可以手动更改,尽管总是 2 的幂,所以求和很简单)。这里的问题是必须使用常量分配共享内存,但我还需要将值从主机传递给内核。我在哪里声明维度n以便它对 CPU 可见(用于传递给内核)并可用于声明共享内存的大小(在内核内)?

我的代码结构如下:

main.cu我称内核为:

然后在kernel.cu我有:

numbers是一个表示 1024 个矩阵的数组,dimension是行和列的长度,num_states是 1024,fitness_return是一个长度为 1024 的数组,用于保存每个矩阵的适应度值。在内核中,共享内存是用 的平方硬编码的dimensiondimension在这个例子中也是 4)。

我在哪里以及如何声明dimension它可以用来分配共享内存以及调用内核,这样我只需要dimension在一个地方更新?谢谢你的帮助。

0 投票
1 回答
136 浏览

cuda - 同一个线程两次访问同一个内存库会导致冲突吗?

我正在研究一个可以减少向量的内核。它基本上将向量中的所有位置相加并将结果存储在位置 0 中。

我正在遵循这个方案,包含 512 个浮点元素块:

减少计划

编码:

奇怪的是,我预计会出现共享的银行冲突,但我没有。在第一次迭代中,线程 0 将位置 0 和位置 256 相加,它们位于同一组中。线程 1 将位置 1 和位置 257 相加,依此类推。

所有这些操作都需要扭曲中的每个线程从同一银行获得 2 个不同的值,但是,我没有任何冲突:

结果

我错过了什么?

0 投票
1 回答
755 浏览

cuda - 动态并行 - 将共享内存的内容传递给生成的块?

虽然我已经编写了一段时间的 CUDA 内核,但我还没有使用动态并行 (DP)。我遇到了一项我认为可能适合的任务;但是,我希望能够使用 DP 的方式是:

如果 block 发现它需要更多线程来完成它的工作,它就会产生它们;它将“它所知道的”传递给它的衍生线程——本质上,它的共享内存的内容,每个衍生线程块在其自己的共享内存中获得一份副本;线程使用它们的父线程“知道”的东西来确定他们需要继续做什么,然后去做。

但是,AFAICT 不会发生这种共享内存的“继承”。全局内存(和通过内核参数的常量内存)是“父”DP内核块可以将信息传递给其“子”块的唯一方式吗?

0 投票
1 回答
488 浏览

cuda - 我的内核代码可以告诉它有多少共享内存可用吗?

运行设备端 CUDA 代码是否有可能知道为运行内核网格的每个块分配了多少(静态和/或动态)共享内存?

在主机端,您知道启动的内核拥有(或将拥有)多少共享内存,因为您自己设置了该值;但是设备端呢?在该大小的上限中很容易编译,但该信息不可用(除非明确传递)给设备。是否有获取它的 on-GPU 机制?CUDA C Programming Guide似乎没有讨论这个问题(在共享内存部分之内或之外)。