t0 and steps < 100000: steps += 1 starts, states, _ = seg[x] i = bisect.bisect_left(starts, t) - 1 if i < 0: acc[(x, 'unknown')] += t - t0 break st, lo = states[i], max(starts[i], t0) if st in (S_RUN, S_CORE, S_HOST, S_SLEEP) or st >= len(STATES): acc[(x, STATES[st] if st < len(STATES) else f's{st}')] += t - lo t = lo continue if st == 0: acc[(x, 'off')] += t - lo t = lo continue # a wait from starts[i] to the next state change: the last signal for x inside it ended it end = starts[i + 1] if i + 1 < len(starts) else t ws, wk = wakes[x] j = bisect.bisect_right(ws, end) - 1 if j >= 0 and ws[j] >= starts[i] and wk[j]: w = ws[j] if w <= t0: acc[(x, 'wake latency')] += t - t0 break acc[(x, 'wake latency')] += max(0, t - w) x, t = wk[j], min(t, w) else: acc[(x, 'wait ' + STATES[st] + ' (no guest waker)')] += t - lo t = lo tot.update(acc) lens.append(t1 - t0) n = len(lens) if not n: raise SystemExit('fewer than two presents recorded') frame_ms = sum(lens) / n / 1e6 print(f'{n} frames, mean interval {frame_ms:.2f} ms; critical path per frame (ms, share):') for (h, kind), ns in tot.most_common(a.top): print(f' {ns / n / 1e6:7.3f} {100 * ns / sum(lens):5.1f}% {label(h, threads):24} {kind}') by_kind = Counter() for (h, kind), ns in tot.items(): by_kind[kind] += ns print('by kind: ' + ', '.join(f'{k} {v / n / 1e6:.2f}' for k, v in by_kind.most_common())) by_thread = Counter() for (h, kind), ns in tot.items(): by_thread[h] += ns print('by thread: ' + ', '.join(f'{label(h, threads)} {v / n / 1e6:.2f}' for h, v in by_thread.most_common(10))) if __name__ == '__main__': main()