From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ingo Molnar Subject: Re: [patch 0/3] [Announcement] Performance Counters for Linux Date: Fri, 5 Dec 2008 08:03:29 +0100 Message-ID: <20081205070329.GA30874@elte.hu> References: <20081204225345.654705757@linutronix.de> <18744.29747.728320.652642@cargo.ozlabs.ibm.com> <20081205063131.GB12785@elte.hu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline In-Reply-To: <20081205063131.GB12785@elte.hu> Sender: linux-kernel-owner@vger.kernel.org To: Paul Mackerras Cc: Thomas Gleixner , LKML , linux-arch@vger.kernel.org, Andrew Morton , Stephane Eranian , Eric Dumazet , Robert Richter , Arjan van de Veen , Peter Anvin , Peter Zijlstra , Steven Rostedt , David Miller List-Id: linux-arch.vger.kernel.org * Ingo Molnar wrote: > This can be done in a very natural way with our abstraction, and the > "hello.c" example happens to do exactly that: multiple people pointed out that we have not posted hello.c :-/ Here's a simple standalone example (full working code attached below): int main(void) { unsigned long long count1, count2; int fd1, fd2, ret; fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1); assert(fd1 >= 0); fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1); assert(fd1 >= 0); for (;;) { ret = read(fd1, &count1, sizeof(count1)); assert(ret == 8); ret = read(fd2, &count2, sizeof(count2)); assert(ret == 8); printf("counter1 value: %Ld instructions\n", count1); printf("counter2 value: %Ld cachemisses\n", count2); sleep(1); } return 0; } which gives this output (one readout per second): titan:~/perf-counter-test> ./simple counter1 value: 0 instructions counter2 value: 0 cachemisses counter1 value: 23 instructions counter2 value: 0 cachemisses counter1 value: 2853 instructions counter2 value: 6 cachemisses counter1 value: 5736 instructions counter2 value: 7 cachemisses counter1 value: 8619 instructions counter2 value: 8 cachemisses counter1 value: 11502 instructions counter2 value: 8 cachemisses ^C You need our patchset but then the code below will work just fine. No libraries, no context setup, nothing - just what is more interesting: the counter and profiling data. Ingo -----------------> /* * Very simple performance counter testcase. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __x86_64__ # define __NR_perf_counter_open 295 #endif #ifdef __i386__ # define __NR_perf_counter_open 333 #endif int perf_counter_open(int hw_event_type, unsigned int hw_event_period, unsigned int record_type, pid_t pid, int cpu) { return syscall(__NR_perf_counter_open, hw_event_type, hw_event_period, record_type, pid, cpu); } enum hw_event_types { PERF_COUNT_CYCLES, PERF_COUNT_INSTRUCTIONS, PERF_COUNT_CACHE_REFERENCES, PERF_COUNT_CACHE_MISSES, PERF_COUNT_BRANCH_INSTRUCTIONS, PERF_COUNT_BRANCH_MISSES, }; int main(void) { unsigned long long count1, count2; int fd1, fd2, ret; fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1); assert(fd1 >= 0); fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1); assert(fd1 >= 0); for (;;) { ret = read(fd1, &count1, sizeof(count1)); assert(ret == 8); ret = read(fd2, &count2, sizeof(count2)); assert(ret == 8); printf("counter1 value: %Ld instructions\n", count1); printf("counter2 value: %Ld cachemisses\n", count2); sleep(1); } return 0; } From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.mail.elte.hu ([157.181.151.9]:41335 "EHLO mx2.mail.elte.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750966AbYLEHD7 (ORCPT ); Fri, 5 Dec 2008 02:03:59 -0500 Date: Fri, 5 Dec 2008 08:03:29 +0100 From: Ingo Molnar Subject: Re: [patch 0/3] [Announcement] Performance Counters for Linux Message-ID: <20081205070329.GA30874@elte.hu> References: <20081204225345.654705757@linutronix.de> <18744.29747.728320.652642@cargo.ozlabs.ibm.com> <20081205063131.GB12785@elte.hu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20081205063131.GB12785@elte.hu> Sender: linux-arch-owner@vger.kernel.org List-ID: To: Paul Mackerras Cc: Thomas Gleixner , LKML , linux-arch@vger.kernel.org, Andrew Morton , Stephane Eranian , Eric Dumazet , Robert Richter , Arjan van de Veen , Peter Anvin , Peter Zijlstra , Steven Rostedt , David Miller Message-ID: <20081205070329.F0rIcLvC-5J_v-reCvtDB_qkvTqsYFpWU5KZGeSX-Tw@z> * Ingo Molnar wrote: > This can be done in a very natural way with our abstraction, and the > "hello.c" example happens to do exactly that: multiple people pointed out that we have not posted hello.c :-/ Here's a simple standalone example (full working code attached below): int main(void) { unsigned long long count1, count2; int fd1, fd2, ret; fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1); assert(fd1 >= 0); fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1); assert(fd1 >= 0); for (;;) { ret = read(fd1, &count1, sizeof(count1)); assert(ret == 8); ret = read(fd2, &count2, sizeof(count2)); assert(ret == 8); printf("counter1 value: %Ld instructions\n", count1); printf("counter2 value: %Ld cachemisses\n", count2); sleep(1); } return 0; } which gives this output (one readout per second): titan:~/perf-counter-test> ./simple counter1 value: 0 instructions counter2 value: 0 cachemisses counter1 value: 23 instructions counter2 value: 0 cachemisses counter1 value: 2853 instructions counter2 value: 6 cachemisses counter1 value: 5736 instructions counter2 value: 7 cachemisses counter1 value: 8619 instructions counter2 value: 8 cachemisses counter1 value: 11502 instructions counter2 value: 8 cachemisses ^C You need our patchset but then the code below will work just fine. No libraries, no context setup, nothing - just what is more interesting: the counter and profiling data. Ingo -----------------> /* * Very simple performance counter testcase. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __x86_64__ # define __NR_perf_counter_open 295 #endif #ifdef __i386__ # define __NR_perf_counter_open 333 #endif int perf_counter_open(int hw_event_type, unsigned int hw_event_period, unsigned int record_type, pid_t pid, int cpu) { return syscall(__NR_perf_counter_open, hw_event_type, hw_event_period, record_type, pid, cpu); } enum hw_event_types { PERF_COUNT_CYCLES, PERF_COUNT_INSTRUCTIONS, PERF_COUNT_CACHE_REFERENCES, PERF_COUNT_CACHE_MISSES, PERF_COUNT_BRANCH_INSTRUCTIONS, PERF_COUNT_BRANCH_MISSES, }; int main(void) { unsigned long long count1, count2; int fd1, fd2, ret; fd1 = perf_counter_open(PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1); assert(fd1 >= 0); fd2 = perf_counter_open(PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1); assert(fd1 >= 0); for (;;) { ret = read(fd1, &count1, sizeof(count1)); assert(ret == 8); ret = read(fd2, &count2, sizeof(count2)); assert(ret == 8); printf("counter1 value: %Ld instructions\n", count1); printf("counter2 value: %Ld cachemisses\n", count2); sleep(1); } return 0; }