cs: reduce PLT_LINKLET_TIMES overhead

This commit is contained in:
Matthew Flatt 2019-06-11 16:42:44 -06:00
parent 41dc6f1335
commit b1632232ca

View File

@ -1,10 +1,9 @@
(define region-times (make-eq-hashtable)) (define perf-regions (make-eq-hashtable))
(define region-gc-times (make-eq-hashtable)) (define-record perf-region (time gc-time count memory))
(define region-counts (make-eq-hashtable))
(define region-memories (make-eq-hashtable))
(define current-start-time '()) (define current-perf-frame #f)
(define current-gc-start-time '())
(define-record perf-frame (start gc-start nested-delta nested-gc-delta next))
(define performance-thread-id (get-thread-id)) (define performance-thread-id (get-thread-id))
@ -37,122 +36,143 @@
(syntax-rules () (syntax-rules ()
[(_ label e ...) (measure-performance-region label (lambda () e ...))])) [(_ label e ...) (measure-performance-region label (lambda () e ...))]))
(define (label->perf-region label)
(or (hashtable-ref perf-regions label #f)
(let ([r (make-perf-region 0 0 0 0)])
(hashtable-set! perf-regions label r)
r)))
(define (measure-performance-region label thunk) (define (measure-performance-region label thunk)
(cond (cond
[(and measure-performance? [(and measure-performance?
(eqv? (get-thread-id) performance-thread-id)) (eqv? (get-thread-id) performance-thread-id))
(with-interrupts-disabled (set! current-perf-frame (make-perf-frame (current-process-milliseconds)
(set! current-start-time (cons (current-process-milliseconds) current-start-time)) (current-gc-milliseconds)
(set! current-gc-start-time (cons (current-gc-milliseconds) current-gc-start-time))) 0
0
current-perf-frame))
(begin0 (begin0
(thunk) (thunk)
(with-interrupts-disabled (let ([f current-perf-frame])
(let ([delta (- (current-process-milliseconds) (car current-start-time))] (when f ; avoid crash if thread swaps mangle stack update
[gc-delta (- (current-gc-milliseconds) (car current-gc-start-time))]) (let ([delta (- (current-process-milliseconds) (perf-frame-start f) (perf-frame-nested-delta f))]
(hashtable-update! region-times label (lambda (v) (+ v delta)) 0) [gc-delta (- (current-gc-milliseconds) (perf-frame-gc-start f) (perf-frame-nested-gc-delta f))]
(hashtable-update! region-gc-times label (lambda (v) (+ v gc-delta)) 0) [r (label->perf-region label)])
(hashtable-update! region-counts label add1 0) (set-perf-region-time! r (+ (perf-region-time r) delta))
(set! current-start-time (cdr current-start-time)) (set-perf-region-gc-time! r (+ (perf-region-gc-time r) gc-delta))
(set! current-gc-start-time (cdr current-gc-start-time)) (set-perf-region-count! r (+ (perf-region-count r) 1))
(let loop ([l current-start-time] [gc-l current-gc-start-time]) (let ([next (perf-frame-next f)])
(unless (null? l) (set! current-perf-frame next)
(set-car! l (+ (car l) delta)) (when next
(set-car! gc-l (+ (car gc-l) gc-delta)) (set-perf-frame-nested-delta! next (+ delta (perf-frame-nested-delta f) (perf-frame-nested-delta next)))
(loop (cdr l) (cdr gc-l)))))))] (set-perf-frame-nested-gc-delta! next (+ gc-delta (perf-frame-nested-gc-delta f) (perf-frame-nested-gc-delta next)))))))))]
[else (thunk)])) [else (thunk)]))
(define (add-performance-memory! label delta) (define (add-performance-memory! label delta)
(when measure-performance? (when measure-performance?
(with-interrupts-disabled (with-interrupts-disabled
(hashtable-update! region-memories label (lambda (v) (+ v delta)) 0)))) (let ([r (label->perf-region label)])
(set-perf-region-memory! r (+ (perf-region-memory r) delta))))))
(define (linklet-performance-init!) (define (linklet-performance-init!)
(hashtable-set! region-times 'boot (let ([r (label->perf-region 'boot)])
(time->ms (sstats-cpu (statistics))))) (set-perf-region-time! r (time->ms (sstats-cpu (statistics))))))
(define (linklet-performance-report!) (define (linklet-performance-report!)
(when measure-performance? (when measure-performance?
(for-each (lambda (s) (let ([region-times (make-eq-hashtable)]
(let ([label (if (#%memq (car s) register-allocation-passes) [region-gc-times (make-eq-hashtable)]
'regalloc [region-counts (make-eq-hashtable)]
'other)]) [region-memories (make-eq-hashtable)])
(let-values ([(count cpu gc-cpu bytes) (apply values (cdr s))]) (hash-table-for-each perf-regions
(hashtable-update! region-times label (lambda (v) (+ v (time->ms cpu))) 0) (lambda (k r)
(hashtable-update! region-gc-times label (lambda (v) (+ v (time->ms gc-cpu))) 0) (hashtable-set! region-times k (perf-region-time r))
(hashtable-update! region-counts label (lambda (v) (max count v)) 0)))) (hashtable-set! region-gc-times k (perf-region-gc-time r))
(#%$pass-stats)) (hashtable-set! region-counts k (perf-region-count r))
(let* ([total (apply + (hash-table-map region-times (lambda (k v) (round (inexact->exact v)))))] (let ([m (perf-region-memory r)])
[gc-total (apply + (hash-table-map region-gc-times (lambda (k v) v)))] (unless (zero? m)
[name-len (apply max (hash-table-map region-times (lambda (k v) (string-length (symbol->string k)))))] (hashtable-set! region-memories k m)))))
[len (string-length (number->string total))] (for-each (lambda (s)
[gc-len (string-length (number->string gc-total))] (let ([label (if (#%memq (car s) register-allocation-passes)
[categories '((read (read-bundle faslin-code)) 'regalloc
(comp-ffi (comp-ffi-call comp-ffi-back)) 'other)])
(run (instantiate outer)) (let-values ([(count cpu gc-cpu bytes) (apply values (cdr s))])
(compile (compile-linklet compile-nested)) (hashtable-update! region-times label (lambda (v) (+ v (time->ms cpu))) 0)
(compile-pass (regalloc other)))] (hashtable-update! region-gc-times label (lambda (v) (+ v (time->ms gc-cpu))) 0)
[region-subs (make-eq-hashtable)] (hashtable-update! region-counts label (lambda (v) (max count v)) 0))))
[region-gc-subs (make-eq-hashtable)]) (#%$pass-stats))
(define (lprintf fmt . args) (let* ([total (apply + (hash-table-map region-times (lambda (k v) (round (inexact->exact v)))))]
(log-message root-logger 'error (apply #%format fmt args) #f)) [gc-total (apply + (hash-table-map region-gc-times (lambda (k v) v)))]
(define (pad v w combine) [name-len (apply max (hash-table-map region-times (lambda (k v) (string-length (symbol->string k)))))]
(let ([s (#%format "~a" v)]) [len (string-length (number->string total))]
(combine (make-string (max 0 (- w (string-length s))) #\space) [gc-len (string-length (number->string gc-total))]
s))) [categories '((read (read-bundle faslin-code))
(define (pad-left v w) (pad v w string-append)) (comp-ffi (comp-ffi-call comp-ffi-back))
(define (pad-right v w) (pad v w (lambda (p s) (string-append s p)))) (run (instantiate outer))
(define (report level label n n-extra units extra) (compile (compile-linklet compile-nested))
(lprintf ";; ~a~a~a ~a~a ~a~a" (compile-pass (regalloc other)))]
(make-string (* level 2) #\space) [region-subs (make-eq-hashtable)]
(pad-right label name-len) [region-gc-subs (make-eq-hashtable)])
(make-string (* (- 3 level) 2) #\space) (define (lprintf fmt . args)
(pad-left (round (inexact->exact n)) len) (log-message root-logger 'error (apply #%format fmt args) #f))
n-extra (define (pad v w combine)
units (let ([s (#%format "~a" v)])
extra)) (combine (make-string (max 0 (- w (string-length s))) #\space)
(define (ht->sorted-list ht) s)))
(list-sort (lambda (a b) (< (cdr a) (cdr b))) (define (pad-left v w) (pad v w string-append))
(hash-table-map ht cons))) (define (pad-right v w) (pad v w (lambda (p s) (string-append s p))))
(define (sum-values ht keys key subs) (define (report level label n n-extra units extra)
(define sub-ht (make-eq-hashtable)) (lprintf ";; ~a~a~a ~a~a ~a~a"
(hashtable-set! subs key sub-ht) (make-string (* level 2) #\space)
(let loop ([keys keys]) (pad-right label name-len)
(cond (make-string (* (- 3 level) 2) #\space)
[(null? keys) 0] (pad-left (round (inexact->exact n)) len)
[else n-extra
(let* ([sub-key (car keys)] units
[v (hashtable-ref ht sub-key 0)]) extra))
(hashtable-set! sub-ht sub-key v) (define (ht->sorted-list ht)
(hashtable-delete! ht sub-key) (list-sort (lambda (a b) (< (cdr a) (cdr b)))
(+ v (loop (cdr keys))))]))) (hash-table-map ht cons)))
(define (report-time level label n gc-ht) (define (sum-values ht keys key subs)
(report level label n (define sub-ht (make-eq-hashtable))
(#%format " [~a]" (pad-left (hashtable-ref gc-ht label 0) gc-len)) (hashtable-set! subs key sub-ht)
'ms (let loop ([keys keys])
(let ([c (hashtable-ref region-counts label 0)]) (cond
(if (zero? c) [(null? keys) 0]
"" [else
(#%format " ; ~a times" c))))) (let* ([sub-key (car keys)]
(for-each (lambda (l) [v (hashtable-ref ht sub-key 0)])
(let* ([cat (car l)] (hashtable-set! sub-ht sub-key v)
[subs (cadr l)] (hashtable-delete! ht sub-key)
[t (sum-values region-times subs cat region-subs)] (+ v (loop (cdr keys))))])))
[gc-t (sum-values region-gc-times subs cat region-gc-subs)]) (define (report-time level label n gc-ht)
(unless (and (zero? t) (zero? gc-t)) (report level label n
(hashtable-set! region-times cat t) (#%format " [~a]" (pad-left (hashtable-ref gc-ht label 0) gc-len))
(hashtable-set! region-gc-times cat gc-t)))) 'ms
categories) (let ([c (hashtable-ref region-counts label 0)])
(let loop ([ht region-times] [gc-ht region-gc-times] [level 0]) (if (zero? c)
(for-each (lambda (p) ""
(let ([label (car p)] (#%format " ; ~a times" c)))))
[n (cdr p)]) (for-each (lambda (l)
(report-time level label n gc-ht) (let* ([cat (car l)]
(let ([sub-ht (hashtable-ref region-subs label #f)] [subs (cadr l)]
[sub-gc-ht (hashtable-ref region-gc-subs label #f)]) [t (sum-values region-times subs cat region-subs)]
(when sub-ht [gc-t (sum-values region-gc-times subs cat region-gc-subs)])
(loop sub-ht sub-gc-ht (add1 level)))))) (unless (and (zero? t) (zero? gc-t))
(ht->sorted-list ht))) (hashtable-set! region-times cat t)
(report 0 'total total (#%format " [~a]" gc-total) 'ms "") (hashtable-set! region-gc-times cat gc-t))))
(lprintf ";;") categories)
(for-each (lambda (p) (report 0 (car p) (/ (cdr p) 1024 1024) "" 'MB "")) (let loop ([ht region-times] [gc-ht region-gc-times] [level 0])
(ht->sorted-list region-memories))))) (for-each (lambda (p)
(let ([label (car p)]
[n (cdr p)])
(report-time level label n gc-ht)
(let ([sub-ht (hashtable-ref region-subs label #f)]
[sub-gc-ht (hashtable-ref region-gc-subs label #f)])
(when sub-ht
(loop sub-ht sub-gc-ht (add1 level))))))
(ht->sorted-list ht)))
(report 0 'total total (#%format " [~a]" gc-total) 'ms "")
(lprintf ";;")
(for-each (lambda (p) (report 0 (car p) (/ (cdr p) 1024 1024) "" 'MB ""))
(ht->sorted-list region-memories))))))