问题标签 [false-sharing]

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 投票
2 回答
510 浏览

c++ - 多线程效率不高:调试虚假共享?

我有以下代码,它从一开始就启动多个线程(一个线程池)(startWorkers())。随后,在某个时候,我有一个装满myWorkObject实例的容器,我想同时使用多个工作线程对其进行处理。就内存使用而言,myWorkObject它们与另一个完全隔离。现在让我们假设 myWorkObject 有一个doWorkIntenseStuffHere()需要一些 cpu 时间来计算的方法。

在对以下代码进行基准测试时,我注意到此代码不能很好地随线程数扩展,并且初始化/同步工作线程的开销超过了多线程的好处,除非有 3-4 个线程处于活动状态。我已经研究了这个问题并阅读了关于错误共享问题的信息,并且我认为我的代码遇到了这个问题。但是,我想调试/分析我的代码以查看是否存在某种饥饿/错误共享。我怎样才能做到这一点?请随时批评我的代码,因为我仍在学习很多关于内存/cpu 和多线程的知识。

0 投票
3 回答
2755 浏览

c++ - 虚假共享和 128 字节对齐/填充

在做一些关于无锁/无等待算法的研究时,我偶然发现了错误共享问题。再深入一点,我找到了 Folly 的源代码(Facebook 的 C++ 库),更具体地说,是这个头文件FOLLY_ALIGN_TO_AVOID_FALSE_SHARING宏的定义(目前在第 130 行)。乍一看最让我惊讶的是这个值:128(即:而不是64)......

AFAIK,现代 CPU 上的缓存块长度为 64 字节,实际上,到目前为止,我在这件事上找到的所有资源,包括来自 Intel 的这篇文章,都谈到了 64 字节对齐填充,以帮助解决错误共享。

尽管如此,Facebook 的人们仍会在需要时将他们的班级成员对齐并填充到 128 字节。然后我发现了上面FOLLY_ALIGN_TO_AVOID_FALSE_SHARING定义的解释的开头:

虽然它给了我更多细节,但我仍然觉得我需要一些见解。我很好奇在大量使用原子操作的情况下,连续缓存行的同步或对它们的任何 RMW 操作如何相互干扰有人可以告诉我这怎么可能发生?

0 投票
1 回答
1326 浏览

c# - 并行框架,避免虚假共享

最近,我回答了一个关于优化可能的可并行化方法以生成任意基数的每个排列的问题。我发布了一个类似于Parallelized, bad implementation code block list 的答案,有人几乎立即指出了这一点:

这几乎可以保证给您虚假共享,并且可能会慢很多倍。(归功于gjvdkamp

他们是对的,这是死亡缓慢。也就是说,我研究了该主题,并找到了一些有趣的材料和建议(仅限 MSDN 杂志存档,.NET Matters: False Sharing)来对抗它。如果我理解正确,当线程访问连续内存(比如说,可能支持它的数组ConcurrentStack)时,可能会发生错误共享。


对于水平线以下的代码,aBytes是:

对于我自己的测试,我想获得这个运行的并行版本并且真正更快,所以我基于原始代码创建了一个简单的示例。6limits[0]是我懒惰的选择——我的电脑有 6 个内核。

单线程块 平均运行时间:10s0059ms

并行化,实施不佳 平均运行时间:81s729ms,~ 8700 次争用

并行化,?? 执行 平均运行时间:5s833ms,92 次争用

我很高兴我有一个比单线程版本更快的实现。我预计结果接近 10s / 6 或 1.6 秒左右,但这可能是一个幼稚的期望。

我的问题是对于实际上比单线程版本更快的并行化实现,是否有可以应用于操作的进一步优化?我想知道与并行化相关的优化,而不是用于计算值的算法的改进。具体来说:

  • 我知道将存储和填充为 astruct而不是的优化byte[],但它与并行化无关(或者是吗?)
  • 我知道可以使用波纹进位加法器对所需值进行惰性评估,但与struct优化相同。
0 投票
1 回答
865 浏览

c - 在不使用填充的情况下防止虚假共享

我目前正在学习pthreadsC 并遇到了错误共享的问题。我想我理解它的概念,并且我尝试过一些实验。

下面是我一直在玩的一个简短的程序。最终,我将把它改成一个程序来获取大量整数并并行求和。

我的问题是,是否可以在不使用填充的情况下防止虚假共享?这里struct s的大小为 64 字节,因此每个结构都在自己的缓存行上(假设缓存行是 64 字节)。我不确定如何在没有填充的情况下实现并行性。

另外,如果我要对一个大小在 1000-50,000 字节之间的数组求和,我该如何防止错误共享?我可以使用类似的程序来填充它吗?我目前的想法是将大数组中的每个 int 放入一个数组中struct s,然后使用并行性对其求和。但是我不确定这是否是最佳解决方案。

0 投票
1 回答
4686 浏览

caching - cache-line-ping-pong 和 false 共享是否相同?

对于我的学士论文,我必须评估多核系统上的常见问题。

在一些书中,我读到了关于虚假共享的书籍,以及在其他关于缓存线乒乓球的书籍中。具体问题听起来很熟悉,那么这些问题是相同的问题但被赋予了其他名称吗?有人可以给我详细讨论这些主题的书籍名称吗?(我已经有 Darry Glove、Tanenbaum 的文学作品……)

0 投票
1 回答
276 浏览

c++ - 尽管错误共享,但速度提高

我一直在对 OpenMP 进行一些测试,并使这个程序由于数组“sum”的错误共享而无法扩展。我遇到的问题是它确实可以扩展。更糟”:

  • 带 1 个线程:4 秒 (icpc)、4 秒 (g++)
  • 有 2 个线程:2 秒 (icpc)、2 秒 (g++)
  • 4线程:0.5秒(icpc),1秒(g++)

我真的没有得到英特尔编译器从 2 个线程到 4 个线程的加速。但最重要的是:为什么缩放如此好,即使它应该表现出错误的共享?

0 投票
2 回答
6134 浏览

caching - Intel 和 AMD 使用哪种缓存一致性协议?

对于我的学士论文,我必须分析虚假共享对多核系统的影响。因此,寻找我在维基百科上遇到的不同缓存一致性协议类型,英特尔开发了 MESIF 缓存一致性协议,但没有信息表明英特尔也使用它。

查看手册英特尔® 64 和 IA-32 架构开发人员手册:卷。3A除了 MESI 协议,我找不到任何关于 MESIF 的信息。所以问题是,英特尔不使用自己的缓存一致性协议。还是我在错误的文档中搜索它。

0 投票
0 回答
35 浏览

caching - 对虚假分享的观察

我有一个关于虚假分享的观察,请看这段代码:

在这里,sum_a可能需要不断地从主内存(而不是从缓存中)重新读取x,即使inc_b' 的并发修改 y应该是无关紧要的。

通过甲骨文的网站,我读到了这个解释:

来自不同处理器的同一高速缓存行中的单个元素同时更新会使整个高速缓存行无效,即使这些更新在逻辑上彼此独立。缓存行的单个元素的每次更新都会将该行标记为无效。访问同一行中不同元素的其他处理器会看到标记为无效的行。他们被迫从内存或其他地方获取该行的更新副本,即使访问的元素尚未修改。这是因为缓存一致性是在缓存行的基础上维护的,而不是针对单个元素。因此,互连流量和开销将会增加。此外,当缓存行更新正在进行时,对行中元素的访问被禁止.

我的观察很简单:
如果我读的是真的,怎么可能存在“脏读”的问题???

0 投票
1 回答
177 浏览

c - 霍格维尔的虚假分享!算法

我正在尝试实现Hogwild!线性 SVM算法,但我的实现遇到了错误的共享问题。

我的代码在下面,但背景是我正在尝试计算哪些样本未能通过我的测试并制作和更新由该组向量给出的。野猪!(据我了解)只是完全异步地对同一内存进行更新。由于不正确的时间更新,这将在数学意义上产生“噪音”。

可悲的是,当我尝试进行这些异步更新时,L1 缓存已失效并且必须重新获取。下面是我的代码。

有没有一种在不丢失异步的情况下修复这种错误共享的好方法?(我更像是一名数学家,而不是计算机科学家)。提到使用不同的优化级别可以解决这个问题。

0 投票
0 回答
399 浏览

caching - 在 OpenMP 并行循环中避免错误共享

考虑一个并行循环,其中每个线程都将在一个私有向量上进行计算dudz(izfirst:izlast)。在我的实现中,我想完成两件事:

  • 进入此并行区域时不分配内存(每个时间步都会调用)
  • 避免虚假共享(我目前正在重写代码以避免过多的缓存未命中)

为避免问题 1,我正在考虑创建dudz(izfirst:izlast,nproc)每个线程仅访问的数组dudz(:, omp_id),但这是否容易受到错误共享的影响?为了避免错误共享,我正在考虑使用private(dudz),但这不分配内存吗?

以下代码可以适用于我的任一解决方案,但哪个更好?是否有第三种选择可以解决我的两个问题?

谢谢你的任何建议。