Ian*_*ham -1 cuda bank-conflict gpu-shared-memory
我正在编写一些 N 体模拟代码,在 CUDA 中针对 Volta 和图灵系列卡进行短程交互。我计划使用共享内存,但我不太清楚这样做时如何避免银行冲突。由于我的交互是本地的,我计划将我的粒子数据分类到本地组中,我可以将这些数据发送到每个 SM 的共享内存(还没有担心粒子的邻居正在从另一个 SM 工作。为了变得更好性能(避免库冲突),仅每个线程从/向共享内存的不同地址读取/写入就足够了,但每个线程可以无序访问该内存而不会受到惩罚?
我看到的所有信息似乎只提到内存被合并以从全局内存到共享内存的复制,但我没有看到任何关于扭曲(或整个 SM)中的线程是否关心共享内存中的合并。
为了获得良好的性能(避免库冲突),仅每个线程从/向共享内存的不同地址读取/写入就足够了,但每个线程可以无序访问该内存而不会受到惩罚?
bank 冲突只可能发生在单个 warp 中正在执行共享内存访问的线程之间,并且只能在每个指令(发出)的基础上发生。我在这里谈论的指令是 SASS(GPU 汇编代码)指令,但是应该可以直接从 CUDA C++ 源代码中的共享内存引用中识别出来。
没有银行冲突这样的想法:
由于其自身的活动,给定线程可以以任何模式访问共享内存,而无需担心或可能发生共享内存回冲突。Bank 冲突仅由单个 warp 中的 2 个或更多线程引起,由于特定的共享内存指令或访问,在整个 warp 范围内发出。
此外,每个线程从/向不同的地址读取/写入是不够的。粗略地说,对于给定的发出指令(即给定的访问),warp 中的每个线程必须从不同的bank读取,否则它必须从与 warp(广播)中的另一个地址相同的地址读取。
让我们假设我们指的是 32 位 bank,以及 32 个 bank 的排列。共享内存可以很容易地想象为一种二维排列:
Addr Bank
v 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
64 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
96 96 97 98 ...
Run Code Online (Sandbox Code Playgroud)
我们看到地址/索引/偏移量/位置 0、32、64、96 等在同一组中。地址 1、33、65、97 等在同一个 bank 中,依此类推,对于 32 个 bank 中的每一个。当共享内存的地址在这种 2D 排列中可视化时,银行就像位置列
对发布到 warp 的给定指令(加载或存储)的非库冲突访问的要求是:
并以稍微不同的方式重复上面的一些陈述:
| 归档时间: |
|
| 查看次数: |
442 次 |
| 最近记录: |