diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-11-30 12:49:55 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-11-30 17:05:25 -0500 |
commit | 5c891f3840a7a330c96d7203d4bb5be6fa033724 (patch) | |
tree | bf8fdacde9410f396e382eebfdb924be479e8d7e | |
parent | 020bb75a6deeca5ebeae531dc7378c157affc8fd (diff) |
perf session: Allocate chunks of sample objects
The ordered sample code allocates singular reference objects struct
sample_queue which have 48byte size on 64bit and 20 bytes on 32bit. That's
silly. Allocate ~64k sized chunks and hand them out.
Performance gain: ~ 15%
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20101130163820.398713983@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/session.c | 21 | ||||
-rw-r--r-- | tools/perf/util/session.h | 3 |
2 files changed, 19 insertions, 5 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 9fef587ff11f..52672dad1fe9 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -114,6 +114,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
114 | self->repipe = repipe; | 114 | self->repipe = repipe; |
115 | INIT_LIST_HEAD(&self->ordered_samples.samples); | 115 | INIT_LIST_HEAD(&self->ordered_samples.samples); |
116 | INIT_LIST_HEAD(&self->ordered_samples.sample_cache); | 116 | INIT_LIST_HEAD(&self->ordered_samples.sample_cache); |
117 | INIT_LIST_HEAD(&self->ordered_samples.to_free); | ||
117 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); | 118 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); |
118 | 119 | ||
119 | if (mode == O_RDONLY) { | 120 | if (mode == O_RDONLY) { |
@@ -403,10 +404,10 @@ static void perf_session_free_sample_buffers(struct perf_session *session) | |||
403 | { | 404 | { |
404 | struct ordered_samples *os = &session->ordered_samples; | 405 | struct ordered_samples *os = &session->ordered_samples; |
405 | 406 | ||
406 | while (!list_empty(&os->sample_cache)) { | 407 | while (!list_empty(&os->to_free)) { |
407 | struct sample_queue *sq; | 408 | struct sample_queue *sq; |
408 | 409 | ||
409 | sq = list_entry(os->sample_cache.next, struct sample_queue, list); | 410 | sq = list_entry(os->to_free.next, struct sample_queue, list); |
410 | list_del(&sq->list); | 411 | list_del(&sq->list); |
411 | free(sq); | 412 | free(sq); |
412 | } | 413 | } |
@@ -538,10 +539,13 @@ static void __queue_sample_event(struct sample_queue *new, | |||
538 | } | 539 | } |
539 | } | 540 | } |
540 | 541 | ||
542 | #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) | ||
543 | |||
541 | static int queue_sample_event(event_t *event, struct sample_data *data, | 544 | static int queue_sample_event(event_t *event, struct sample_data *data, |
542 | struct perf_session *s) | 545 | struct perf_session *s) |
543 | { | 546 | { |
544 | struct list_head *sc = &s->ordered_samples.sample_cache; | 547 | struct ordered_samples *os = &s->ordered_samples; |
548 | struct list_head *sc = &os->sample_cache; | ||
545 | u64 timestamp = data->time; | 549 | u64 timestamp = data->time; |
546 | struct sample_queue *new; | 550 | struct sample_queue *new; |
547 | 551 | ||
@@ -553,10 +557,17 @@ static int queue_sample_event(event_t *event, struct sample_data *data, | |||
553 | if (!list_empty(sc)) { | 557 | if (!list_empty(sc)) { |
554 | new = list_entry(sc->next, struct sample_queue, list); | 558 | new = list_entry(sc->next, struct sample_queue, list); |
555 | list_del(&new->list); | 559 | list_del(&new->list); |
560 | } else if (os->sample_buffer) { | ||
561 | new = os->sample_buffer + os->sample_buffer_idx; | ||
562 | if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER) | ||
563 | os->sample_buffer = NULL; | ||
556 | } else { | 564 | } else { |
557 | new = malloc(sizeof(*new)); | 565 | os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); |
558 | if (!new) | 566 | if (!os->sample_buffer) |
559 | return -ENOMEM; | 567 | return -ENOMEM; |
568 | list_add(&os->sample_buffer->list, &os->to_free); | ||
569 | os->sample_buffer_idx = 2; | ||
570 | new = os->sample_buffer + 1; | ||
560 | } | 571 | } |
561 | 572 | ||
562 | new->timestamp = timestamp; | 573 | new->timestamp = timestamp; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index e4a7ff2ba8d5..5bf6efa3788a 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -19,7 +19,10 @@ struct ordered_samples { | |||
19 | u64 max_timestamp; | 19 | u64 max_timestamp; |
20 | struct list_head samples; | 20 | struct list_head samples; |
21 | struct list_head sample_cache; | 21 | struct list_head sample_cache; |
22 | struct list_head to_free; | ||
23 | struct sample_queue *sample_buffer; | ||
22 | struct sample_queue *last_sample; | 24 | struct sample_queue *last_sample; |
25 | int sample_buffer_idx; | ||
23 | }; | 26 | }; |
24 | 27 | ||
25 | struct perf_session { | 28 | struct perf_session { |