问题标签 [memory-bandwidth]

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 投票
0 回答
204 浏览

c++ - clCreateBuffer() 在 CPU 上分配?

我正在使用 C++ 和 OpenCL 上的(循环)神经网络来获得一些深度学习的低级经验。现在我有一个简单的前向传播内核,它产生了奇怪的低性能;该设置与大多数深度学习设置一样受到内存限制,并且基于一些粗略的分析,我得到的内存带宽约为 2 GB/s。调用 clGetDeviceInfo() 确认我正在使用我的板载 GPU (GTX 960m);我怀疑我用 clCreateBuffer() 分配的内存不知何故最终落在了 CPU 上,这会导致传输速率徘徊在 2 GB/s 左右,正如本文所建议的那样。我分配的缓冲区对于 GPU 来说不应该太大;最大的是 1024*1024*4 字节 = 4 MB(权重),其中只有 12 个被创建。

对 clCreateBuffer() 的调用,带有一些上下文:

OpenCL 可能将内存分配给 CPU 而不是活动设备的一些原因是什么?我能做些什么来强制在 GPU 上分配内存?

编辑:一个简单的测试产生了这个内存带宽值,这与建议的 CPU 和 GPU 之间的 5-6 GB/s 带宽一致。

0 投票
2 回答
351 浏览

cuda - 测量CUDA中某个指令或代码行的内存带宽的方法?

有没有办法测量 CUDA 中某个内存指令或代码行的内存带宽?(nvprof 可以输出整个内核的内存带宽。)如果 clock() 函数是唯一的方法,那么计算带宽的公式是什么?(每个{指令或代码行}的合并地址数除以时钟()差异?)

我想查看某个指令或代码行是否过度/未充分利用内存带宽。(例如,MSHR ..)

我在 x86_64 位 linux 系统上有两个设备,GTX980(Maxwell,sm_52)和 P100(Pascal,sm_60)。

0 投票
1 回答
671 浏览

performance - 最近几代 CPU 架构的每个周期的加载/存储

受到这个答案的启发

沙桥和 haswell SSE2/AVX/AVX2 的每周期 FLOPS

对于 Sandy/Ivy Bridge、Broad/Haswell、Sky/Kaby Lake,可以在核心上发布多少个 just-loads/loads-and-stores?AMD Bulldozer、Jaguar 和 Zen 的数量也很有趣。

PS - 我知道由于缓存/内存带宽的原因,这可能不是一个可持续的速率,我只是在询问问题。

0 投票
3 回答
1326 浏览

x86 - 什么特别地将 x86 缓存行标记为脏 - 任何写入,还是需要显式更改?

这个问题专门针对现代 x86-64 缓存一致性架构 - 我很欣赏其他 CPU 上的答案可能会有所不同。

如果我写入内存,MESI 协议要求先将缓存行读入缓存,然后在缓存中修改(将值写入缓存行,然后将其标记为脏)。在较旧的 write-though 微架构中,这将触发缓存行被刷新,在回写下,被刷新的缓存行可能会延迟一段时间,并且在两种机制下都可能发生一些写组合(更可能是写回) . 而且我知道这如何与访问同一数据缓存行的其他内核交互 - 缓存侦听等。

我的问题是,如果存储与缓存中已经存在的值精确匹配,如果没有一个位被翻转,是否有任何英特尔微架构注意到这一点并且不会将该行标记为脏,从而可能避免该行被标记为排他性的,以及在某些时候会出现的写回内存开销?

当我对更多循环进行矢量化时,我的矢量化操作组合原语不会显式检查值的变化,并且在 CPU/ALU 中这样做似乎很浪费,但我想知道底层缓存电路是否可以在没有显式编码的情况下做到这一点(例如存储微操作或缓存逻辑本身)。随着跨多个内核的共享内存带宽越来越成为资源瓶颈,这似乎是一个越来越有用的优化(例如,重复对同一内存缓冲区进行归零——如果它们已经从 RAM 中重新读取值,我们就不会重新读取它们)在缓存中,但强制写回相同的值似乎很浪费)。写回缓存本身就是对此类问题的一种认可。

我可以礼貌地要求保留“理论上”或“这真的没关系”的答案吗?我知道内存模型是如何工作的,我正在寻找的是关于如何编写相同值的确凿事实(而不是避免存储)将影响内存总线的争用,您可以放心地假设这是一台运行多个工作负载的机器,这些工作负载几乎总是受内存带宽的限制。另一方面,对芯片不这样做的确切原因的解释(我悲观地假设他们不这样做)将是有启发性的......

更新: 这里有一些符合预期的答案https://softwareengineering.stackexchange.com/questions/302705/are-there-cpus-that-perform-this-possible-l1-cache-write-optimization但仍然有很多猜测“它一定很难,因为它没有完成”,并说在主 CPU 内核中这样做会很昂贵(但我仍然想知道为什么它不能成为实际缓存逻辑本身的一部分)。

更新(2020 年): Travis Downs 发现了硬件商店消除的证据,但似乎仅针对零且仅在数据未命中 L1 和 L2 的情况下,即便如此,并非在所有情况下都是如此。强烈推荐他的文章,因为它更详细...... https://travisdowns.github.io/blog/2020/05/13/intel-zero-opt.html

更新(2021 年): Travis Downs 现在发现证据表明这种零存储优化最近已在微码中被禁用......更多细节来自源本人 https://travisdowns.github.io/blog/2021/06/17 /rip-zero-opt.html

0 投票
1 回答
470 浏览

x86-64 - SIMD 内在和内存总线大小 - CPU 如何在单个内存读取中获取所有 128/256 位?

你好论坛 - 我有一些关于 SIMD 内在函数的类似/相关问题,我在网上搜索了这些问题,包括 stackoverflow,但没有找到好的答案,因此请求您的帮助。

基本上,我试图了解 64 位 CPU 如何在一次读取中获取所有 128 位,以及这种操作的要求是什么。

  1. CPU 会在一次内存操作中从内存中获取所有 128 位,还是会执行两次 64 位读取?
  2. CPU 制造商是否需要特定大小的内存总线,例如,对于 64 位 CPU,英特尔是否需要 128 位总线来进行 SSE 内存绑定操作?
  3. 这些操作是否取决于内存总线大小、通道数和内存模块数?
0 投票
5 回答
2251 浏览

performance - 英特尔性能监视器计数器能否用于测量内存带宽?

英特尔 PMU 能否用于测量每核读/写内存带宽使用情况?这里的“内存”是指 DRAM(即,不命中任何缓存级别)。

0 投票
0 回答
26 浏览

windows - Windows 中的内存使用情况如何影响性能

我在英特尔第二代 i5 移动架构上运行具有 4GB DDR3 1066 的 Windows 10。

我主要来自 OSX 背景,内存一直是我关心的问题,因为我更喜欢打开许多选项卡。我注意到在 OSX 上,内存使用与应用程序的性能没有太大关系,只要它没有完全饱和,但在我的 iMac 上很容易我可以运行 80% 的内存并且没有发现明显的延迟或卡顿。但是在 Windows 上,我发现内存是我系统的主要瓶颈,我知道升级到 8 或 16GB 内存将是我的升级途径。但是,我很想了解为什么当我使 80% 的内存饱和时,我的系统会明显变慢,而 OSX 似乎可以很好地处理它。是带宽限制吗?我知道 Windows NT 和 Darwin 是完全不同的内核,我很想了解这对相同的使用场景有何不同影响。

先感谢您。

0 投票
0 回答
198 浏览

mpi - 为什么我的套接字间 MPI 发送带宽大于内存带宽?

我在 NERSC 的 Cori 的 Haswell 节点上进行了 osu_mbw_mr 测试(来自 OSU 微基准测试),得到了一些我无法解释的奇怪结果。

该节点有两个插槽,每个插槽都有一个 16 核 Intel Xeon 处理器 E5-2698 v3。两个处理器通过 QPI 连接。可以在此处此处找到节点和 CPU 的详细信息。

如果我是正确的,节点的最大内存带宽是 68GB/sx 2 CPUs = 136GB/s,QPI 的最大带宽是 9.6 GT/sx 2 Links x 2 Bytes/link = 38.4 GB/s,双向。我还用 STREAM 测量了内存带宽。拷贝带宽约为110GB/s,接近理论值。这太棒了。

我在一个节点上运行 osu_mbw_mr,其中 32 个 MPI 等级,并将前 16 个等级放在套接字 0 上,接下来的 16 个等级放在套接字 1 上。

在 osu_mbw_mr 中,每个 rank 分配一个发送缓冲区(s_buf)和一个接收缓冲区(r_buf),然后初始化它们(因此我假设缓冲区通过第一次接触与它们的 NUMA 域具有亲和力)。在 32 个等级中,等级 0~15 背靠背发送固定数量的消息(窗口大小)到配对的接收等级,即 16~31。我使用了克雷 MPICH。我认为无论 MPI 是如何实现的,最终效果都是“将数据从 s_buf(跨 QPI 链接)复制到 r_buf”。

以下是我的测试结果。我不明白为什么 8K、16K 等消息大小的带宽如此之大,并且突然下降到 2MB 消息。带宽大于 QPI 带宽,甚至大于 DRAM 带宽。在我的理论中,带宽应该是 QPI 带宽的一半(19.2GB/s),因为我们从套接字 0 向 1 单向发送数据。

怎么了?谢谢。


正如一条评论提醒我的那样,OSU 微基准在发送中重复使用相同的发送缓冲区。所以数据基本上在缓存中。这次我使用了 Intel MPI Benchmarks,它可以选择发送缓存外数据。我在同一台机器上运行它

srun -n 32 -c 2 -m block:block --cpu_bind=cores,verbose ./IMB-MPI1 Uniband -off_cache 40,64

并得到了这些数字,正如预期的那样低于内存带宽。

0 投票
0 回答
41 浏览

opengl - 使用 OpenGL 渲染纹理需要多少内存访问?

使用 OpenGL,我想计算渲染帧所需的吞吐量。

假设情况更糟,我有 (1) 一个帧缓冲区和 (2) 8 个全屏纹理,并且纹理最终覆盖整个屏幕(但是,纹理可能是平面矩形,但不是 1:1 比例)。

因此,每个像素都是从 9 个 RGB 像素调整而来(假设所有纹理都具有一定程度的透明度),在理想情况下,您将准确读取 9 个像素,然后将结果保存在帧缓冲区中。当然,通过过滤它可能会读取更多像素(特别是如果纹理不直等)

如何计算内存访问次数的近似值。所以如果我的视频板说它有 40Gb/s 的限制,我可以确保我有足够的带宽来支持满载?

评论中要求的一些细节:

帧/纹理大小:3840 x 2160 (4K)
预期帧速率:30 FPS
GPU:NVidia(至少是最新的 Maxwell 或 Pascal 之一)

0 投票
13 回答
15359 浏览

c++ - 当 95% 的情况下的值是 0 或 1 时,对非常大的数组进行随机访问的任何优化?

对非常大的数组的随机访问是否有任何可能的优化(我目前使用uint8_t,我在问什么更好)

当数组中任意位置的值为

  • 95%的情况为01 ,
  • 24%的情况下,
  • 在其他1%的情况下,在3255之间?

那么,有什么比uint8_t数组更好的呢?应该尽可能快地以随机顺序循环整个数组,这对 RAM 带宽来说非常沉重,因此当有多个线程同时为不同的数组执行此操作时,当前整个 RAM 带宽很快就饱和了。

我问是因为拥有如此大的数组(10 MB)感觉非常低效,而实际上除了 5% 之外,几乎所有的值都是 0 或 1。所以当数组中所有值的 95% 时实际上只需要 1 位而不是 8 位,这将减少内存使用量几乎一个数量级。感觉必须有一个内存效率更高的解决方案,这将大大减少所需的 RAM 带宽,因此随机访问也明显更快。