【问题标题】:Measure contention in wait-free multi-threaded java programs测量无等待多线程 Java 程序中的争用
【发布时间】:2014-05-13 11:56:38
【问题描述】:

我有一个二叉搜索树的无等待实现,但我无法找出衡量线程争用的具体方法。这里的争用是指尝试同时访问同一块内存的线程数。

到目前为止,我已经搜索了 ThreadMXBean 和 ThreadInfo 类,但是由于没有涉及到锁,所以我还没有找到任何解决方案。

【问题讨论】:

  • 看看执行并发更新的方法使用了多少CPU时间。没有争用,CAS 几乎不需要时间……
  • 我已经测量了每个线程的 CPU 时间,但这似乎并没有让我知道争用。但是您的评论使我找到了一种衡量争用的有趣方法。最大和最小线程 CPU 时间之间的差异应该让我知道延迟总是由于争用!
  • lock free(又名wait free)算法的关键在于它们不包含等待操作。唯一可能发生的情况是必须重复更新操作,因为并发更新干扰了更新。与任何其他操作一样,重复将消耗 100% 的 CPU 时间。这里衡量争用的唯一方法是衡量重复次数。除非算法实现记录自己重试,否则您必须测量更新操作的 CPU 时间(这将引发争用)并将其与整体线程执行时间进行比较。

标签: java multithreading performance contention


【解决方案1】:

如果没有高昂的性能成本,就无法衡量对“内存位置”的争用。直接测量(例如,正确同步的计数器包装所有访问)将引入人为瓶颈,这将破坏测试的可靠性。

“同一时间”在您要测量的尺度上被松散地定义,因为在给定时间内只有一个 CPU“拥有”内存中的特定位置。在这种情况下,您可以做的最好的事情是测量 CPU 处理内存冲突的速率,例如通过硬件计数器。这样做需要了解给定平台上的内存子系统。此外,机器(= CPU)状态的硬件计数器属性,而不是内存状态;换句话说,您可以估计特定指令经历了多少次冲突,而不是有多少 CPU 访问了给定的内存位置。

【讨论】:

  • 测试的可靠性值得担心。你能给我任何硬件计数器的链接吗?谢谢!
【解决方案2】:

在争用源中尝试测量是错误的方法。无论如何,争吵的原因可能是什么?!

因此,首先,设置一个基准测试套件,该套件在您的数据结构上运行典型的访问模式,并绘制不同线程数的性能图表。这是一个很好的例子 nitro cache performance page.

如果你的缩放几乎是线性的:恭喜,你完成了!

如果您不是线性扩展,则需要更多洞察力。现在您需要将系统作为一个整体进行分析,并查看原因是什么,例如用于 CPU 流水线停顿。最好的方法是为此使用低开销跟踪。在 Linux 上,您可以使用 OProfile。 OProfile 还支持 Java,它可以帮助您将 JIT 机器代码与您的 Java 程序相关联。

【讨论】:

  • 假设我们谈论的是一个列表,线程争先从节点修改字段。除了第一个之外的所有线程然后竞相修改新附加的节点。这就是争论。感谢您的链接!
  • 如果想找到锁争用的区域,我建议从高级别开始使用采样分析器,例如HPROF。由于它是采样,因此您可以调整施加的开销。
猜你喜欢
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多