-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcache-analysis.wal
More file actions
203 lines (183 loc) · 6.6 KB
/
cache-analysis.wal
File metadata and controls
203 lines (183 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
(defmacro define-callback args
(define name (first args))
(define params (second args))
(define body (rest (rest args)))
`(define ,name (lambda ,params ,@body)))
(defmacro define-cache-metric body
(define name body[0])
(define extra-functions
(filter (fn [x] x)
(for/list [expr (rest body)]
(if (&& (list? expr)
(> (length expr) 2)
(= (first expr) 'define-callback)
(! (in (second expr) '(on-response on-drop final))))
(list (symbol->string (second expr)) (second expr))
#f))))
`(define ,name
(let ()
,@(rest body)
(define obj
(array ["name" ,(symbol->string name)]
["extra" (array ,@extra-functions)]))
(when (defined? 'on-response)
(seta obj "on-response" on-response))
(when (defined? 'on-drop)
(seta obj "on-drop" on-drop))
(when (defined? 'final)
(seta obj "final" final))
obj)))
(module cache-analysis
(defun analyze-cache [metrics time-start time-end]
(step time-start)
(define req-time INDEX)
;; Flatten all extra callbacks into a list
(define extra-callbacks
(fold (fn [acc x] (+ acc x)) '()
(for/list [metric metrics]
(mapa (fn [name func] func) (geta metric "extra")))))
(while (<= INDEX time-end)
(when (cache-sampling)
(unless (cache-request)
(for [callback extra-callbacks] (callback)))
(when (cache-request)
(set! req-time INDEX)
(for [metric metrics]
(when (in "on-request" metric)
((geta metric "on-request") req-time)))
(step-until (do (for [callback extra-callbacks] (callback))
(|| (cache-response)
(cache-request-drop))))
(cond
[(= INDEX MAX-INDEX) #f]
[(cache-response)
(for [metric metrics]
(when (in "on-response" metric)
((geta metric "on-response") req-time INDEX time-end)))]
[(cache-request-drop)
(for [metric metrics]
(when (in "on-drop" metric)
((geta metric "on-drop") req-time INDEX time-end)))])))
;; if we reached the end of the trace stop
(unless (step) (set! time-end 0)))
;; call finalization functions and collect results
(for/list [metric metrics]
(when (in "final" metric)
(list (geta metric "name")
((geta metric "final"))))))
;; Hit-Miss rate
(define-cache-metric cache/hit-rate
(define requests 0)
(define hits 0)
(defun on-response [req-time resp-time d]
(inc requests)
(when (= (- resp-time req-time) 0)
(inc hits)))
(defun final []
(if requests
(/ hits requests)
"no requests")))
;; Average delay
(define-cache-metric cache/average-delay
(define responses 0)
(define acc-delay 0)
(define-callback on-response [req rsp end]
(inc responses)
(set! acc-delay (+ acc-delay (- rsp req))))
(defun final []
(if responses
(/ acc-delay responses)
"no requests")))
;; Average delay of misses
(define-cache-metric cache/average-miss-delay
(define responses 0)
(define acc-delay 0)
(define-callback on-response [req rsp end]
(when (!= req rsp)
(inc responses))
(set! acc-delay (+ acc-delay (- rsp req))))
(defun final []
(if responses
(/ acc-delay responses)
"no requests")))
;; Parallel-ready version of the average-delay metric
(define-cache-metric cache/average-delay/parallel
(define responses 0)
(define acc-delay 0)
(defun on-response [req rsp end]
(when (<= rsp end)
(inc responses))
(set! acc-delay (+ acc-delay (- rsp req))))
(defun final []
(list acc-delay responses)))
;; Collect delays
(define-cache-metric cache/delays-by-time
(define delays (array))
(defun on-response [s n d]
(seta delays s d))
(defun final [] delays))
;; Calculate buckets
(define-cache-metric cache/delay-buckets
(define buckets (array))
(defun on-response [req-time resp-time d]
(define delay (- resp-time req-time))
(seta buckets
delay
(+ 1 (geta/default buckets 0 delay))))
(defun final [] buckets))
;; Print all requests
(define-cache-metric cache/print
(defun on-response [req res end]
(print TS@(- (- res req)) " -> " TS " (" (- res req) ")")))
(define-cache-metric cache/print-misses
(defun on-response [req res end]
(when (- res req)
(print TS@(- (- res req)) " -> " TS " (" (- res req) ")"))))
(define window-size 4000)
(define-cache-metric cache/sliding-window
(define delays (array))
(define window-start 0)
(define window '())
(define res '())
(define-callback collect []
(unless (cache-request)
(set! window (+ window 0)))
(when (> (length window) window-size)
(set! res (append res (list window-start (average window))))
(set! window-start TS)
(set! window '())))
(define-callback on-response [req resp end]
(set! window (+ window (- resp req))))
(defun final [] res))
;; Average delay per function
; Exemplary values
; (define elf-functions
; '(("main" 644 768)
; ("memcpy" 768 892)
; ("print_array" 24 180)
; ("printf" 1324 1716)
; ("print_str" 180 260)
; ("putchar" 892 948)
; ("sort" 260 644)))
(define-cache-metric cache/function-delays
(define functions (array))
(defun on-response [s n d]
(for [f-range elf-functions]
(when (&& (>= (cache-addr) f-range[1])
(<= (cache-addr) f-range[2]))
(define row (geta/default functions '(0 0 0) f-range[0]))
(seta functions f-range[0]
(list (+ row[0] 1) (+ row[1] d))))))
(defun final []
(mapa (fn [key value] (list key (/ value[1] value[0]))) functions)))
(provide analyze-cache
cache/hit-rate
cache/average-delay
cache/average-miss-delay
cache/average-delay/parallel
cache/delay-buckets
cache/delays-by-time
cache/function-delays
cache/sliding-window
cache/print
cache/print-misses))