diff options
| author | Paul Eggert | 2012-10-01 23:30:40 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-10-01 23:30:40 -0700 |
| commit | b3ecad33ae977f9dd0bdd3e0a10cd8603f54a398 (patch) | |
| tree | 9641b9d035dc733b9f3600557becdcb0ffc31290 /src | |
| parent | 8cb51b66fcb7a0954437108f8a1d05d6af6dcf89 (diff) | |
| download | emacs-b3ecad33ae977f9dd0bdd3e0a10cd8603f54a398.tar.gz emacs-b3ecad33ae977f9dd0bdd3e0a10cd8603f54a398.zip | |
Count overruns when profiling; change units to ns.
* lisp/profiler.el (profiler-sampling-interval): Change units
from ms to ns, multiplying the default by 1000000 so that
it remains 1 ms.
(profiler-report-cpu-line-format): Give enough room for
the maximum counters on 64-bit hosts.
(profiler-report-render-calltree-1): Call them "CPU samples",
not "Time (ms)", since they are not milliseconds now (and
never really were).
* src/profiler.c (handle_profiler_signal): Count sampling intervals, not ms.
Give extra weight to samples after overruns, to attempt to count
the time more accurately.
(setup_cpu_timer): Change sampling interval units from ms to ns, since
the underlying primitives nominally do ns.
(Fprofiler_cpu_start): Document the change. Mention that
the sampling intervals are only approximate.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/profiler.c | 31 |
2 files changed, 32 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index a199a7b12e5..a7b35a8572d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2012-10-02 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Count overruns when profiling; change units to ns. | ||
| 4 | * profiler.c (handle_profiler_signal): Count sampling intervals, not ms. | ||
| 5 | Give extra weight to samples after overruns, to attempt to count | ||
| 6 | the time more accurately. | ||
| 7 | (setup_cpu_timer): Change sampling interval units from ms to ns, since | ||
| 8 | the underlying primitives nominally do ns. | ||
| 9 | (Fprofiler_cpu_start): Document the change. Mention that | ||
| 10 | the sampling intervals are only approximate. | ||
| 11 | |||
| 1 | 2012-10-02 Stefan Monnier <monnier@iro.umontreal.ca> | 12 | 2012-10-02 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 13 | ||
| 3 | * frame.c (Fmake_terminal_frame): Prefer safer CONSP over !NILP. | 14 | * frame.c (Fmake_terminal_frame): Prefer safer CONSP over !NILP. |
diff --git a/src/profiler.c b/src/profiler.c index 2f082edc390..3282b8b335b 100644 --- a/src/profiler.c +++ b/src/profiler.c | |||
| @@ -128,8 +128,8 @@ static void evict_lower_half (log_t *log) | |||
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | /* Record the current backtrace in LOG. COUNT is the weight of this | 130 | /* Record the current backtrace in LOG. COUNT is the weight of this |
| 131 | current backtrace: milliseconds for CPU counts, and the allocation | 131 | current backtrace: interrupt counts for CPU, and the allocation |
| 132 | size for memory logs. */ | 132 | size for memory. */ |
| 133 | 133 | ||
| 134 | static void | 134 | static void |
| 135 | record_backtrace (log_t *log, EMACS_INT count) | 135 | record_backtrace (log_t *log, EMACS_INT count) |
| @@ -220,7 +220,7 @@ static Lisp_Object cpu_log; | |||
| 220 | /* Separate counter for the time spent in the GC. */ | 220 | /* Separate counter for the time spent in the GC. */ |
| 221 | static EMACS_INT cpu_gc_count; | 221 | static EMACS_INT cpu_gc_count; |
| 222 | 222 | ||
| 223 | /* The current sampling interval in milliseconds. */ | 223 | /* The current sampling interval in nanoseconds. */ |
| 224 | static EMACS_INT current_sampling_interval; | 224 | static EMACS_INT current_sampling_interval; |
| 225 | 225 | ||
| 226 | /* Signal handler for sampling profiler. */ | 226 | /* Signal handler for sampling profiler. */ |
| @@ -235,11 +235,20 @@ handle_profiler_signal (int signal) | |||
| 235 | not expect the ARRAY_MARK_FLAG to be set. We could try and | 235 | not expect the ARRAY_MARK_FLAG to be set. We could try and |
| 236 | harden the hash-table code, but it doesn't seem worth the | 236 | harden the hash-table code, but it doesn't seem worth the |
| 237 | effort. */ | 237 | effort. */ |
| 238 | cpu_gc_count = saturated_add (cpu_gc_count, current_sampling_interval); | 238 | cpu_gc_count = saturated_add (cpu_gc_count, 1); |
| 239 | else | 239 | else |
| 240 | { | 240 | { |
| 241 | EMACS_INT count = 1; | ||
| 242 | #ifdef HAVE_TIMER_SETTIME | ||
| 243 | if (profiler_timer_ok) | ||
| 244 | { | ||
| 245 | int overruns = timer_getoverrun (profiler_timer); | ||
| 246 | eassert (0 <= overruns); | ||
| 247 | count += overruns; | ||
| 248 | } | ||
| 249 | #endif | ||
| 241 | eassert (HASH_TABLE_P (cpu_log)); | 250 | eassert (HASH_TABLE_P (cpu_log)); |
| 242 | record_backtrace (XHASH_TABLE (cpu_log), current_sampling_interval); | 251 | record_backtrace (XHASH_TABLE (cpu_log), count); |
| 243 | } | 252 | } |
| 244 | } | 253 | } |
| 245 | 254 | ||
| @@ -255,16 +264,18 @@ setup_cpu_timer (Lisp_Object sampling_interval) | |||
| 255 | struct sigaction action; | 264 | struct sigaction action; |
| 256 | struct itimerval timer; | 265 | struct itimerval timer; |
| 257 | struct timespec interval; | 266 | struct timespec interval; |
| 267 | int billion = 1000000000; | ||
| 258 | 268 | ||
| 259 | if (! RANGED_INTEGERP (1, sampling_interval, | 269 | if (! RANGED_INTEGERP (1, sampling_interval, |
| 260 | (TYPE_MAXIMUM (time_t) < EMACS_INT_MAX / 1000 | 270 | (TYPE_MAXIMUM (time_t) < EMACS_INT_MAX / billion |
| 261 | ? (EMACS_INT) TYPE_MAXIMUM (time_t) * 1000 + 999 | 271 | ? ((EMACS_INT) TYPE_MAXIMUM (time_t) * billion |
| 272 | + (billion - 1)) | ||
| 262 | : EMACS_INT_MAX))) | 273 | : EMACS_INT_MAX))) |
| 263 | return NOT_RUNNING; | 274 | return NOT_RUNNING; |
| 264 | 275 | ||
| 265 | current_sampling_interval = XINT (sampling_interval); | 276 | current_sampling_interval = XINT (sampling_interval); |
| 266 | interval = make_emacs_time (current_sampling_interval / 1000, | 277 | interval = make_emacs_time (current_sampling_interval / billion, |
| 267 | current_sampling_interval % 1000 * 1000000); | 278 | current_sampling_interval % billion); |
| 268 | emacs_sigaction_init (&action, deliver_profiler_signal); | 279 | emacs_sigaction_init (&action, deliver_profiler_signal); |
| 269 | sigaction (SIGPROF, &action, 0); | 280 | sigaction (SIGPROF, &action, 0); |
| 270 | 281 | ||
| @@ -315,7 +326,7 @@ setup_cpu_timer (Lisp_Object sampling_interval) | |||
| 315 | DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start, | 326 | DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start, |
| 316 | 1, 1, 0, | 327 | 1, 1, 0, |
| 317 | doc: /* Start or restart the cpu profiler. | 328 | doc: /* Start or restart the cpu profiler. |
| 318 | It takes call-stack samples each SAMPLING-INTERVAL milliseconds. | 329 | It takes call-stack samples each SAMPLING-INTERVAL nanoseconds, approximately. |
| 319 | See also `profiler-log-size' and `profiler-max-stack-depth'. */) | 330 | See also `profiler-log-size' and `profiler-max-stack-depth'. */) |
| 320 | (Lisp_Object sampling_interval) | 331 | (Lisp_Object sampling_interval) |
| 321 | { | 332 | { |