summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYogesh Tillu <yogesh.tillu@linaro.org>2015-04-14 11:36:55 +0530
committerYogesh Tillu <yogesh.tillu@linaro.org>2015-04-15 08:01:49 +0530
commit5bfdec46898d6e9ce6cd9371fcf676ce1856c14e (patch)
tree5016a2b77e261eca5d992a1c47b7b0b65e9df5ae
parent5be680ecefdbd840289134719e532bfba2f57466 (diff)
perf_ev_open:
Added support for all perf hw counter Added getopt support for argument Added print_usage for help Reviewed-by: Anders Roxell <anders.roxell@linaro.org> Signed-off-by: Yogesh Tillu <yogesh.tillu@linaro.org>
-rw-r--r--perf_ev_open.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/perf_ev_open.c b/perf_ev_open.c
index 3550bfd..9b06586 100644
--- a/perf_ev_open.c
+++ b/perf_ev_open.c
@@ -16,21 +16,27 @@
#include <sys/types.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>
+#include <getopt.h>
static int fddev = -1;
-__attribute__((constructor)) static void
-init(void)
+
+static int counter_init(unsigned int counter)
{
static struct perf_event_attr attr;
attr.type = PERF_TYPE_HARDWARE;
- attr.config = PERF_COUNT_HW_CPU_CYCLES;
+ if (counter < 0 || counter > PERF_COUNT_HW_MAX)
+ return -1;
+
+ attr.config = counter;
fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
-}
+ if (fddev == -1) {
+ fprintf(stderr,
+ "Error opening perf_event_open for counter %llx\n"
+ , attr.config);
+ return -1;
+ }
-__attribute__((destructor)) static void
-fini(void)
-{
- close(fddev);
+ return 0;
}
static inline long long cpucycles(void)
@@ -38,10 +44,11 @@ static inline long long cpucycles(void)
long long result = 0;
if (read(fddev, &result, sizeof(result)) < sizeof(result))
return 0;
+
return result;
}
-/* Simple loop body to keep things interested. Make sure it gets inlined. */
+/* loop body to keep things interested. Make sure it gets inlined. */
static inline int
loop(int* __restrict__ a, int* __restrict__ b, int n)
{
@@ -50,22 +57,56 @@ loop(int* __restrict__ a, int* __restrict__ b, int n)
for (i = 0; i < n; ++i)
if (a[i] > b[i])
sum += a[i] + 5;
+
return sum;
}
-int main(int ac, char **av)
+void print_usage(char *argv)
+{
+ printf("Usage: %s -c perf_hw_counter -n length\n"
+ "%s - read perf hardware counters from userspace\n\n"
+ "-c\t perf_hw_counter is enum value of hw counter for platform\n"
+ "Refer to 'enum perf_hw_id'[file <linux/perf_event.h>] for hw\n"
+ "counter enum value in range of 0 to PERF_COUNT_HW_MAX\n"
+ "-n\t Length size array will implement busyloop\n"
+ "e.g.\n"
+ "\t%s -c 0 -n 64\n", argv, argv, argv);
+}
+
+int main(int ac, char *argv[])
{
long long time_start = 0;
long long time_end = 0;
-
+ int option = 0;
+ int len = -1, cnt = -1;
int *a = NULL;
int *b = NULL;
- int len = 0;
- int i, sum = 0;
- if (ac != 2)
- return -1;
- len = atoi(av[1]);
- printf("%s: len = %d\n", av[0], len);
+ int i, result, sum = 0;
+
+ while ((option = getopt(ac, argv, "c:n:")) != -1) {
+ switch (option) {
+ case 'c':
+ cnt = atoi(optarg);
+ break;
+ case 'n':
+ len = atoi(optarg);
+ break;
+ default:
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (len == -1 || cnt == -1) {
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (counter_init(cnt) < 0) {
+ printf("Error: Counter Invalid\n");
+ print_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
a = malloc(len*sizeof(*a));
b = malloc(len*sizeof(*b));
@@ -74,7 +115,7 @@ int main(int ac, char **av)
a[i] = i+128;
b[i] = i+64;
}
- printf("%s: beginning loop\n", av[0]);
+
time_start = time_end = 0;
/* --------------------Critical section-------------- */
time_start = cpucycles();
@@ -82,20 +123,27 @@ int main(int ac, char **av)
sum = loop(a, b, len);
cpucycles();
}
+
time_end = cpucycles();
/* ---------------------------------- */
- printf("sum = %d; Avg time delta[Loop + Read] = %llu\n", sum,
- (time_end - time_start)/1000);
+ result = (time_end-time_start)/1000;
+ printf("\nsum=%d Avg count [ Loop + Read ] = %ld\n", sum,
+ (time_end-time_start)/1000);
time_start = time_end = 0;
/* --------------------Critical section-------------- */
time_start = cpucycles();
for (i = 0; i < 1000; i++)
sum = loop(a, b, len);
+
time_end = cpucycles();
/* ---------------------------------- */
- printf("sum = %d; Avg time delta[Loop]\t = %llu\n", sum,
- (time_end - time_start)/1000);
+ printf("sum=%d Avg count [ Loop ] = %ld\n", sum,
+ (time_end-time_start)/1000);
+ printf("\n--------------------------------------------------------\n");
+ printf("\tDelay[cpucycles]=%d", result-((time_end-time_start)/1000));
+ printf("\n--------------------------------------------------------\n");
free(a);
free(b);
+ close(fddev);
return 0;
}