目前,它们每隔GC周期更新一次。要使它们"连续"更新应该是很简单的,因为大多数(全部?)都是实时累积的。
nwwlzxa71#
https://go.dev/cl/487215提到了这个问题:runtime/metrics: make CPU stats real-time
runtime/metrics: make CPU stats real-time
s4chpxco2#
在重构之后,还需要哪些功能来实现按需CPU统计?
z9gpfhce3#
我遇到的主要问题是 user 时间的单调性问题。这是因为 user 时间是通过从计算出的 total 中减去其他所有内容来计算的。例如,如果在我们进行测量时有一个飞行中的标记辅助(但尚未完成),并且在一小段时间内(小于总标记辅助时间)再进行一次测量(用户时间似乎会突然上升,然后下降)。更具体地说:标记辅助需要 10μs。我们在测量时花费了 5μs。在那一个CPU上,那 5μs 的时间将归属于 user 时间。然后,5μs 后,当它完成时,我们再次进行测量。现在它归属于标记辅助,所以 user 时间可能会看起来倒退。这个问题很复杂,但我们需要像 https://cs.opensource.google/go/go/+/master:src/runtime/mgclimit.go;l=208;drc=70fbc88288143c218fde9f905a38d55505adfb2b;bpv=1;bpt=1 这样更完整的东西。虽然不是不可能,但可能需要大量的工作。
user
total
dw1jzc5e4#
感谢您的解释。在理想解决方案实施之前,正如您所说,这会变得很复杂。那么,在实现理想解决方案之前,我们可以采用一个中间解决方案,让我们大部分时候都能达到目标吗?
这样一来,指标就不会完全按需生成,但仍能保持单调性(这对指标很重要),并且比目前的状态更新要少一些陈旧。
kuhbmx9i5#
要明确的是,标记辅助示例仅仅是一个示例(也许是一个糟糕的示例;我们实际上今天已经可以处理那个了...)。还有其他几个案例,比如GC工作人员积极运行。等待他们完成运行并不是特别有用,因为这相当于等待垃圾回收标记阶段结束。
az31mfrm6#
等待他们运行结束并不是特别有用,因为这相当于等待垃圾回收标记阶段结束。我不建议这样做。我的建议是,如果这是情况的话,提供最后一个快照:
GCWorker1 ---==---------------------- GCWorker2 --------------====--------- MetricsPoller ---||---------||||----------
其中有一个条形图( | ),指标轮询器只会看到最后更新的值。当没有工作线程忙于更新时,按需指标将重新开始。
|
zfciruhq7#
在实践中,我们真的非常努力地让专用的垃圾回收工人坚持他们的P和线程。我认为我们不太可能找到任何宁静。同样,这不仅仅是垃圾回收工人的问题。我们需要确保没有任何未完成的事件,以便它能够正常工作。这基本上是一个STW(停顿时间优化)。
pexxcrt28#
我再次遇到了这个问题( (*) ),在尝试比较Go处理时间与内核处理时间时。基本上:
(/cpu/classes/total - /cpu/classes/idle - /cpu/classes/gc/pause) --------------------------------------------------------------- rusage.ru_utime
我知道度量包建议不要将内核和Go度量进行比较,但在这种情况下,我想观察两者之间的显著差异。回答问题:当Go认为它消耗了X秒/秒,而内核给它的(要少得多)是多少?虽然大多数时候这个比例只是略高于1,但我观察到了一些显著的异常值(例如15倍的比例)。我想排除这种可能性是由于等待GC周期完成后再更新度量所固有的延迟。我不是说这绝对是必要的,可以通过其他方式获得类似的信息,但会变得混乱。这只是一种用途。(*)至少,我认为我做到了。
8条答案
按热度按时间nwwlzxa71#
https://go.dev/cl/487215提到了这个问题:
runtime/metrics: make CPU stats real-time
s4chpxco2#
在重构之后,还需要哪些功能来实现按需CPU统计?
z9gpfhce3#
我遇到的主要问题是
user
时间的单调性问题。这是因为user
时间是通过从计算出的total
中减去其他所有内容来计算的。例如,如果在我们进行测量时有一个飞行中的标记辅助(但尚未完成),并且在一小段时间内(小于总标记辅助时间)再进行一次测量(用户时间似乎会突然上升,然后下降)。更具体地说:标记辅助需要 10μs。我们在测量时花费了 5μs。在那一个CPU上,那 5μs 的时间将归属于user
时间。然后,5μs 后,当它完成时,我们再次进行测量。现在它归属于标记辅助,所以user
时间可能会看起来倒退。这个问题很复杂,但我们需要像 https://cs.opensource.google/go/go/+/master:src/runtime/mgclimit.go;l=208;drc=70fbc88288143c218fde9f905a38d55505adfb2b;bpv=1;bpt=1 这样更完整的东西。虽然不是不可能,但可能需要大量的工作。
dw1jzc5e4#
感谢您的解释。在理想解决方案实施之前,正如您所说,这会变得很复杂。那么,在实现理想解决方案之前,我们可以采用一个中间解决方案,让我们大部分时候都能达到目标吗?
这样一来,指标就不会完全按需生成,但仍能保持单调性(这对指标很重要),并且比目前的状态更新要少一些陈旧。
kuhbmx9i5#
要明确的是,标记辅助示例仅仅是一个示例(也许是一个糟糕的示例;我们实际上今天已经可以处理那个了...)。还有其他几个案例,比如GC工作人员积极运行。等待他们完成运行并不是特别有用,因为这相当于等待垃圾回收标记阶段结束。
az31mfrm6#
等待他们运行结束并不是特别有用,因为这相当于等待垃圾回收标记阶段结束。我不建议这样做。我的建议是,如果这是情况的话,提供最后一个快照:
其中有一个条形图(
|
),指标轮询器只会看到最后更新的值。当没有工作线程忙于更新时,按需指标将重新开始。zfciruhq7#
在实践中,我们真的非常努力地让专用的垃圾回收工人坚持他们的P和线程。我认为我们不太可能找到任何宁静。
同样,这不仅仅是垃圾回收工人的问题。我们需要确保没有任何未完成的事件,以便它能够正常工作。这基本上是一个STW(停顿时间优化)。
pexxcrt28#
我再次遇到了这个问题( (*) ),在尝试比较Go处理时间与内核处理时间时。基本上:
我知道度量包建议不要将内核和Go度量进行比较,但在这种情况下,我想观察两者之间的显著差异。回答问题:当Go认为它消耗了X秒/秒,而内核给它的(要少得多)是多少?虽然大多数时候这个比例只是略高于1,但我观察到了一些显著的异常值(例如15倍的比例)。我想排除这种可能性是由于等待GC周期完成后再更新度量所固有的延迟。
我不是说这绝对是必要的,可以通过其他方式获得类似的信息,但会变得混乱。这只是一种用途。
(*)至少,我认为我做到了。