问题标签 [gpu-atomics]
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.
cuda - Kepler 中如何实现全局原子操作?我使用 gmem 而不是使用 atomics 获得的性能较低
我想知道开普勒中全局原子的实现。
看这段代码:
如果我为此更改第 4 行:
*dst -= 300000.0f;
性能更低!更改是安全的,因为不再有线程将写入此值(输出相同)。
使用原子的内核:~883us 直接使用 gmem 的内核:~903us
我已经跑了好几次了,我总是因为这个变化而受到大约 20 秒的惩罚
更新 似乎没有使用原子的商店总是会在 L2 中产生缺失,而原子版本总是会产生命中......所以我想尝试写入一些被标记为“原子”的位置是不允许的L2 向 gmem 发出另一个请求
cuda - 如何实现涉及多个变量的自定义原子函数?
我想在 CUDA 中实现这个原子函数:
我不相信我可以用任何原子函数来做到这一点。我需要为几个指令锁定几个全局内存位置。我可以用 PTXAS(汇编)代码来实现吗?
cuda - atomicInc() 不工作
我已经使用 atomicInc() 尝试了下面的程序。
输出是:
我不明白为什么它没有增加。谁能帮忙
cuda - CUDA 对全局内存中数组的原子操作
我有一个 CUDA 程序,其内核基本上执行以下操作。
- 我提供了笛卡尔坐标中的 n 个点的列表,例如维度为 dim_x * dim_y 的平面中的 (x_i,y_i)。我相应地调用内核。
- 对于这个平面上的每个点 (x_p,y_p),我通过一个公式计算这 n 个点中的每一个到达那里所需的时间;给定这 n 个点以一定的速度移动。
- 我以 t_0、t_1、...t_n 的递增顺序对这些时间进行排序,其中 t_i 的精度设置为 1。即如果 t'_i=2.3453,那么我将只使用 t_i=2.3。
- 假设时间是从正态分布生成的,我模拟了 3 个最快的时间,以找出这 3 个点最早到达的时间百分比。因此通过随机实验假设 prob_0 = 0.76,prob_1=0.20 和 prob_2=0.04。由于 t_0 在三者中排名第一,因此我还返回了该点的原始索引(在时间排序之前)。说 idx_0 = 5(整数)。
- 因此,对于该平面上的每个点,我都会得到一对(prob,idx)。
假设这些点中的 n/2 是一种,其余的是另一种。生成的示例图像如下所示。
特别是当时间精度设置为 1 时,我注意到唯一 3 个时间元组 (t_0,t_1,t_2) 的数量仅为总数据点的 2.5%,即平面上的点数。这意味着在大多数情况下,内核只能使用先前模拟的值进行无用的模拟。因此,我可以使用一个字典,其键为时间的三元组,值作为索引和概率。由于据我所知和测试,STL 无法在内核内部访问,因此我构造了一个大小为 201000000 的浮点数组。这个选择是通过实验得出的,因为前 3 次都没有超过 20 秒。因此 t_0 可以从 {0.0,0.1,0.2,...,20.0} 中取任何值,因此有 201 个选择。我可以为这样的字典构造一个键,如下所示
- 键 = t_o * 10^6 + t_1 * 10^3 + t_2
就值而言,我可以将其设为 (prob+idx)。由于 idx 是一个整数并且 0.0<=prob<=1.0,我可以稍后检索这两个值
- prob=dict[key]-floor(dict[key])
- idx = floor(dict[key])
所以现在我的内核如下所示
结果与大多数点的原始程序非常相似,但对于某些点来说是错误的。
我很确定这是由于比赛条件造成的。请注意,dict 被初始化为全零。基本思想是使数据结构在字典的特定位置“读取多次写入一次”。
我知道可能有更优化的方法来解决这个问题,而不是分配这么多的内存。在这种情况下请告诉我。但我真的很想了解为什么这个特定的解决方案会失败。特别是我想知道如何在这个设置中使用 atomicAdd 。我没有使用它。
concurrency - CUDA 原子操作和并发内核启动
目前,我开发了一个基于 GPU 的程序,该程序使用多个内核,这些内核通过多个流同时启动。
在我的应用程序中,多个内核需要访问一个队列/堆栈,我计划使用原子操作。
但我不知道原子操作是否在同时启动的多个内核之间起作用。请任何了解 GPU 上原子操作的确切机制或有此问题经验的人帮助我。
cuda - Cuda原子锁:顺序线程
我有一段代码需要严格执行。我为那段代码使用了一个锁,以便内核的每个线程(每个块设置一个线程)原子地执行那段代码。线程的顺序让我感到困扰 - 我需要线程根据它们的索引(或者实际上,按照它们的 blockIdx 的顺序)按时间顺序执行,从 0 到 10(而不是随机的,例如 5、8、3, 0,...等)。有可能这样做吗?
这是一个示例代码:
这给出了以下结果:
我希望这些索引从 0 开始并按时间顺序执行到 9。
我认为修改 Lock 以实现此目的的一种方法如下:
然后通过将索引作为参数传递来初始化锁:
但这让我的电脑停了下来……我可能遗漏了一些明显的东西。
如果有人可以提供帮助,我将不胜感激!
谢谢!!!
c++ - Cuda上的原子添加不起作用..
我的问题是使用 CUDA 找出 n 维球体中的整数点数。我不明白下面的代码有什么问题,但它一直给出 0 输出。CUDA 计算能力为 2.0,工具包版本为 3.10。感谢所有的帮助。
cuda - 如何在 CUDA 中进行原子负载
我的问题是如何在 CUDA 中进行原子负载。原子交换可以模拟原子存储。可以以类似的方式非昂贵地模拟原子负载吗?我可以使用带有 0 的原子添加来以原子方式加载内容,但我认为它很昂贵,因为它执行原子读取-修改-写入,而不仅仅是读取。
cuda - 在 CUDA 中同步多个变量
我的程序有很多 4 字节的字符串,比如“aaaa”“bbbb”“cccc”......我需要收集通过 crc 检查的特定字符串。
因为字符串通过 crc 检查的可能性很小,所以我不想使用非常大的缓冲区来保存所有结果。我更喜欢一一连接的结果,就像输入一样。例如,如果输入为“aaaabbbbcccc”且“bbbb”未通过 crc 检查,则输出字符串应为“aaaacccc”且 output_count 应为 2。
代码如下所示:
显然内存副本不是线程安全的,我知道 atomicAdd 函数可以用于 ++ 操作,但是如何使 output 和 output_count 线程安全?
optimization - 加快许多箱/几个箱的 CUDA 原子计算
我正在尝试优化我在 CUDA 中的直方图计算。它为我提供了相对于相应 OpenMP CPU 计算的出色加速。但是,我怀疑(根据直觉)大多数像素都落入了几个桶中。为了论证的缘故,假设我们有 256 个像素落入让我们说,两个桶。
最简单的方法是这样做似乎是
- 将变量加载到共享内存中
- 如果需要,对 unsigned char 等进行矢量化加载。
- 在共享内存中进行原子添加
- 对全局进行合并写入。
像这样的东西:
当我们减少 bin 的数量时,这个内核的性能(自然地)下降,从 32 个 bin 的大约 45 GB/s 降低到 1 个 bin 的 10 GB/s 左右。争用和共享内存库冲突作为原因给出。我不知道是否有任何方法可以以任何重要的方式删除这些计算中的任何一个。
我还一直在尝试来自 parallelforall 博客的另一个(美丽的)想法,其中涉及使用 __ballot 来获取扭曲结果,然后使用 __popc() 来减少扭曲级别。
这为单个 bin 情况(1 个 bin 为 35-40 GB/s,而 10-15 GB/s 使用原子),但是当我们增加 bin 数量时性能会急剧下降。当我们使用 32 个 bin 运行时,性能下降到大约 5 GB/s。原因可能是因为单线程循环遍历所有 bin,要求 NUM_BINS 循环的并行化。
我尝试了几种并行化 NUM_BINS 循环的方法,但似乎都没有正常工作。例如,可以(非常不雅地)操纵内核为每个 bin 创建一些块。这似乎表现相同,可能是因为我们将再次遭受多个块尝试从全局内存中读取的争用。另外,程序很笨拙。同样,在 y 方向上对 bin 进行并行化也会产生同样令人沮丧的结果。
我尝试的另一个想法是动态并行,为每个 bin 启动一个内核。这是灾难性的缓慢,可能是由于子内核没有真正的计算工作和启动开销。
最有希望的方法似乎是——来自 Nicholas Wilt 的文章
使用这些所谓的私有化直方图,其中包含共享内存中每个线程的 bin,这在表面上对 shmem 的使用非常重要(我们在 Maxwell 上每个 SM 只有 48 kB)。
也许有人可以对这个问题有所了解?我觉得应该去改变算法而不是使用直方图,使用不那么频繁的东西。否则,我想我们只使用原子版本。
编辑:我的问题的上下文是计算用于模式分类的概率密度函数。我们可以通过使用非参数方法(例如 Parzen Windows 或 Kernel Density Estimation)来计算近似直方图(更准确地说是 pdf)。然而,这并没有克服维度问题,因为我们需要对每个 bin 的所有数据点求和,当 bin 的数量变大时,这会变得很昂贵。见这里:Parzen