11#!/usr/bin/env python3
22
33import argparse
4+ import glob
45import json
56import os
67import resource
@@ -155,17 +156,38 @@ def get_rusage_result(rusage: resource.struct_rusage, metric: str) -> Result:
155156 return Result (category = metric , value = value , unit = info .unit )
156157
157158
159+ def evict_caches (patterns : list [str ]) -> None :
160+ evicted = False
161+ for pattern in patterns :
162+ for path in glob .glob (pattern , recursive = True ):
163+ try :
164+ fd = os .open (path , os .O_RDONLY )
165+ except OSError :
166+ continue
167+ try :
168+ os .posix_fadvise (fd , 0 , 0 , os .POSIX_FADV_DONTNEED )
169+ evicted = True
170+ finally :
171+ os .close (fd )
172+ if patterns and not evicted :
173+ print (f"warning: --evict matched no files: { patterns } " , file = sys .stderr )
174+
175+
158176def main (
159177 cmd : list [str ],
160178 output : Path ,
161179 topics : list [str ],
162180 metrics : set [str ],
163181 append : bool = True ,
164182 capture : bool = False ,
183+ evict : list [str ] | None = None ,
165184) -> tuple [str , str ]:
166185 perf_metrics , rusage_metrics = resolve_metrics (metrics )
167186 perf_events = {PERF_METRICS [metric ].event for metric in perf_metrics }
168187
188+ if evict :
189+ evict_caches (evict )
190+
169191 measured = measure_perf (cmd , perf_events , capture = capture )
170192 perf = measured .perf
171193 rusage = resource .getrusage (resource .RUSAGE_CHILDREN )
@@ -191,6 +213,7 @@ class Args(Namespace):
191213 default_metrics : bool
192214 output : Path
193215 append : bool
216+ evict : list [str ]
194217 cmd : str
195218 args : list [str ]
196219
@@ -233,6 +256,13 @@ class Args(Namespace):
233256 action = "store_true" ,
234257 help = "append to the output file instead of overwriting it" ,
235258 )
259+ parser .add_argument (
260+ "--evict" ,
261+ action = "append" ,
262+ default = [],
263+ metavar = "GLOB" ,
264+ help = "drop files matching GLOB from the page cache before measuring, for a cold-cache run. Repeatable." ,
265+ )
236266 parser .add_argument (
237267 "cmd" ,
238268 help = "command to measure the resource usage of" ,
@@ -255,4 +285,5 @@ class Args(Namespace):
255285 topics = args .topic ,
256286 metrics = metrics ,
257287 append = args .append ,
288+ evict = args .evict ,
258289 )
0 commit comments