diff --git a/src/06_optimization/clock/Makefile b/src/06_optimization/clock/Makefile new file mode 100644 index 0000000..8d0e0e8 --- /dev/null +++ b/src/06_optimization/clock/Makefile @@ -0,0 +1,54 @@ +EXE=clock +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O0 -MD -std=gnu11 -D_GNU_SOURCE + +ifeq ($(target),nano) +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) +endif + +ifeq ($(target),host) +EXEC=$(EXE)_h +endif + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip +OBJDUMP=$(TOOLCHAIN)objdump + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ t.txt + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + +dump: all + $(OBJDUMP) -dS $(EXEC) > t.txt + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all dump diff --git a/src/06_optimization/clock/clock.c b/src/06_optimization/clock/clock.c new file mode 100644 index 0000000..ca46040 --- /dev/null +++ b/src/06_optimization/clock/clock.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +void measure (int mode, int samples) +{ + struct timespec start_time; + struct timespec stop_time; + clock_gettime (mode, &start_time); // setup... + clock_gettime (mode, &start_time); + for (int i = 0; i + +int main (void) +{ + int res = 1; + for (int i=0; i<16; i++) + { + res *= 2; + } + + if(res < 10) + { + printf("dead code\n"); + } + + printf("res=%d\n", res); + + return 0; +} diff --git a/src/06_optimization/gpio/Makefile b/src/06_optimization/gpio/Makefile new file mode 100644 index 0000000..274aa5c --- /dev/null +++ b/src/06_optimization/gpio/Makefile @@ -0,0 +1,54 @@ +EXE=gpio +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O1 -MD -std=gnu11 -D_GNU_SOURCE + +ifeq ($(target),nano) +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) +endif + +ifeq ($(target),host) +EXEC=$(EXE)_h +endif + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip +OBJDUMP=$(TOOLCHAIN)objdump + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ t.txt + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + +dump: all + $(OBJDUMP) -dS $(EXEC) > t.txt + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all dump diff --git a/src/06_optimization/gpio/gpio.c b/src/06_optimization/gpio/gpio.c new file mode 100644 index 0000000..1266fbf --- /dev/null +++ b/src/06_optimization/gpio/gpio.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define GPIO_EXPORT "/sys/class/gpio/export" +#define GPIO_UNEXPORT "/sys/class/gpio/unexport" +#define GPIO_GPIOG11 "/sys/class/gpio/gpio203" +#define GPIOG11 "203" + +static int open_gpio() +{ + // unexport pin out of sysfs (reinitialization) + int f = open (GPIO_UNEXPORT, O_WRONLY); + write (f, GPIOG11, strlen(GPIOG11)); + close (f); + + // export pin to sysfs + f = open (GPIO_EXPORT, O_WRONLY); + write (f, GPIOG11, strlen(GPIOG11)); + close (f); + + // config pin + f = open (GPIO_GPIOG11 "/direction", O_WRONLY); + write (f, "out", 3); + close (f); + + // open gpio value attribute + f = open (GPIO_GPIOG11 "/value", O_RDWR); + return f; +} + +/** + * main program... + */ +int main() +{ + cpu_set_t my_set; + CPU_ZERO(&my_set); + CPU_SET(2, &my_set); + sched_setaffinity(0, sizeof(cpu_set_t), &my_set); + + int gpio = open_gpio(); + bool on = false; + struct timespec start_time; + struct timespec stop_time; + clock_gettime (CLOCK_MONOTONIC, &start_time); // setup... + + + // --> measurement with internal timers + clock_gettime (CLOCK_MONOTONIC, &start_time); + for (int i=0; i<1000; i++) { + if (on) { + pwrite (gpio, "1", sizeof("1"), 0); + } else { + pwrite (gpio, "0", sizeof("0"), 0); + } + on = !on; + } + clock_gettime (CLOCK_MONOTONIC, &stop_time); + long long t = (stop_time.tv_nsec - start_time.tv_nsec) + + (stop_time.tv_sec - start_time.tv_sec) * 1000000000; + printf ("pwrite (gpio, \"1\", sizeof(\"1\"), 0) -> %lld ns\n", t/1000); + + + // --> measurement with oscilloscope + while(true) { + if (on) { + pwrite (gpio, "1", sizeof("1"), 0); + } else { + pwrite (gpio, "0", sizeof("0"), 0); + } + on = !on; + } + + return 0; +} diff --git a/src/06_optimization/gprof/Makefile b/src/06_optimization/gprof/Makefile new file mode 100644 index 0000000..ea6dc2d --- /dev/null +++ b/src/06_optimization/gprof/Makefile @@ -0,0 +1,34 @@ +CC?=gcc +CFLAGS=-std=c11 -Wall -pg +SOURCES=$(wildcard *.c) +OBJECTS=$(SOURCES:.c=.o) +EXECUTABLE=example-gprof + +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $(OBJECTS) + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + + +clean: + @rm -f $(OBJECTS) + @rm -f *.d + +clean_all: clean + @rm -f $(EXECUTABLE) + @rm -f perf.data perf.data.old + @rm -f gmon.out gprof.out + + +gprof-generate: all + ./$(EXECUTABLE) + gprof $(EXECUTABLE) > gprof.out + +gprof-read: + less gprof.out + + +-include *.d diff --git a/src/06_optimization/gprof/main.c b/src/06_optimization/gprof/main.c new file mode 100644 index 0000000..a4cd546 --- /dev/null +++ b/src/06_optimization/gprof/main.c @@ -0,0 +1,21 @@ +void func1(void) +{ + for(int i=0; i<0xfffffff; i++); // wait... + return; +} + +void func2(void) +{ + for(int i=0;i<0xfffffff;i++); // wait... + func1(); + return; +} + +int main(void) +{ + for(int i=0;i<0xfffffff;i++); + func1(); + func2(); + + return 0; +} diff --git a/src/06_optimization/gprof/target.mk b/src/06_optimization/gprof/target.mk new file mode 100644 index 0000000..65ac0c7 --- /dev/null +++ b/src/06_optimization/gprof/target.mk @@ -0,0 +1,71 @@ +EXE=example-gprof +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O1 -MD -std=gnu11 -D_GNU_SOURCE -pg + +ifeq ($(target),nano) +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) +endif + +ifeq ($(target),host) +EXEC=$(EXE)_h +endif + +ifeq ($(target),xu3) +TOOLCHAIN_PATH=~/workspace/xu3/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)arm-linux-gnueabihf- +CFLAGS+=-mcpu=cortex-a15.cortex-a7 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/xu3 +EXEC=$(EXE)_a +endif + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip +OBJDUMP=$(TOOLCHAIN)objdump + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ t.txt + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + @rm -f perf.data perf.data.old gmon.out gprof.out + +dump: all + $(OBJDUMP) -dS $(EXEC) > t.txt + +gprof-generate: all + ./$(EXECUTABLE) + gprof $(EXECUTABLE) > gprof.out + +gprof-read: + less gprof.out + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all dump diff --git a/src/06_optimization/mmio/Makefile b/src/06_optimization/mmio/Makefile new file mode 100644 index 0000000..fcf2ee0 --- /dev/null +++ b/src/06_optimization/mmio/Makefile @@ -0,0 +1,54 @@ +EXE=mmio +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O1 -MD -std=gnu11 -D_GNU_SOURCE + +ifeq ($(target),nano) +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) +endif + +ifeq ($(target),host) +EXEC=$(EXE)_h +endif + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip +OBJDUMP=$(TOOLCHAIN)objdump + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ t.txt + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + +dump: all + $(OBJDUMP) -dS $(EXEC) > t.txt + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all dump diff --git a/src/06_optimization/mmio/mmio.c b/src/06_optimization/mmio/mmio.c new file mode 100644 index 0000000..7268e49 --- /dev/null +++ b/src/06_optimization/mmio/mmio.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define GPIO_EXPORT "/sys/class/gpio/export" +#define GPIO_UNEXPORT "/sys/class/gpio/unexport" +#define GPIO_GPIOG11 "/sys/class/gpio/gpio203" +#define GPIOG11 "203" + +static int open_gpio() +{ + // unexport pin out of sysfs (reinitialization) + int f = open (GPIO_UNEXPORT, O_WRONLY); + write (f, GPIOG11, strlen(GPIOG11)); + close (f); + + // export pin to sysfs + f = open (GPIO_EXPORT, O_WRONLY); + write (f, GPIOG11, strlen(GPIOG11)); + close (f); + + // config pin + f = open (GPIO_GPIOG11 "/direction", O_WRONLY); + write (f, "out", 3); + close (f); + + // open gpio value attribute + f = open (GPIO_GPIOG11 "/value", O_RDWR); + return f; +} + +/** + * main program... + */ +int main() +{ + cpu_set_t my_set; + CPU_ZERO(&my_set); + CPU_SET(2, &my_set); + sched_setaffinity(0, sizeof(cpu_set_t), &my_set); + + int gpio = open_gpio(); + pwrite (gpio, "1", sizeof("1"), 0); + pwrite (gpio, "0", sizeof("0"), 0); + + int fd = open ("/dev/mem", O_RDWR); + if (fd == -1) return -1; + off_t psz = getpagesize(); + volatile uint32_t* pio = mmap (0, psz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x01c20000); + volatile uint32_t* dat_pio = pio + (0x810+6*0x24)/4; + + struct timespec start_time; + struct timespec stop_time; + clock_gettime (CLOCK_MONOTONIC, &start_time); // setup... + + // --> measurement with internal timers on gpio + clock_gettime (CLOCK_MONOTONIC, &start_time); + + for (int i=0; i<1000; i++) + *dat_pio ^= (1<<11); + + clock_gettime (CLOCK_MONOTONIC, &stop_time); + long long t = (stop_time.tv_nsec - start_time.tv_nsec) + + (stop_time.tv_sec - start_time.tv_sec) * 1000000000; + printf ("*dat_pio ^= (1<<11) --> %6lld ns\n", t/1000); + + + // --> measurement on internal data with internal timers + volatile uint32_t data = 0; + clock_gettime (CLOCK_MONOTONIC, &start_time); + + for (int i=0; i<1000; i++) + data ^= (1<<11); + + clock_gettime (CLOCK_MONOTONIC, &stop_time); + t = (stop_time.tv_nsec - start_time.tv_nsec) + + (stop_time.tv_sec - start_time.tv_sec) * 1000000000; + printf ("data ^= (1<<11) --> %6lld ns\n", t/1000); + + + // --> measurement with oscilloscope + while(true) { + *dat_pio ^= (1<<11); + } + + return 0; +} diff --git a/src/06_optimization/trace/Makefile b/src/06_optimization/trace/Makefile new file mode 100644 index 0000000..451b10f --- /dev/null +++ b/src/06_optimization/trace/Makefile @@ -0,0 +1,54 @@ +EXE=tracing +SRCS=$(wildcard *.c) + +ifeq ($(target),) +target=nano +endif + +CFLAGS=-Wall -Wextra -g -c -O1 -MD -std=gnu11 -D_GNU_SOURCE + +ifeq ($(target),nano) +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CFLAGS+=-mcpu=cortex-a53 -funwind-tables +##CFLAGS+=-O2 -fno-omit-frame-pointer +OBJDIR=.obj/nano +EXEC=$(EXE) +endif + +ifeq ($(target),host) +EXEC=$(EXE)_h +endif + +CC=$(TOOLCHAIN)gcc +LD=$(TOOLCHAIN)gcc +AR=$(TOOLCHAIN)ar +STRIP=$(TOOLCHAIN)strip +OBJDUMP=$(TOOLCHAIN)objdump + +OBJDIR=.obj/$(target) +OBJS= $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +$(OBJDIR)/%o: %c + $(CC) $(CFLAGS) $< -o $@ + +all: $(OBJDIR)/ $(EXEC) + +$(EXEC): $(OBJS) $(LINKER_SCRIPT) + $(LD) $(OBJS) $(LDFLAGS) -o $@ + +$(OBJDIR)/: + mkdir -p $(OBJDIR) + +clean: + rm -Rf $(OBJDIR) $(EXEC) $(EXEC)_s *~ t.txt + +clean_all: clean + rm -Rf .obj $(EXE) $(EXE)_s $(EXE)_a $(EXE)_a_s $(EXE)_h $(EXE)_h_s + +dump: all + $(OBJDUMP) -dS $(EXEC) > t.txt + +-include $(OBJS:.o=.d) + +.PHONY: all clean clean_all dump diff --git a/src/06_optimization/trace/example1.sh b/src/06_optimization/trace/example1.sh new file mode 100644 index 0000000..24fa81d --- /dev/null +++ b/src/06_optimization/trace/example1.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# 1. example +echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable +./tracing & +pidof tracing > /sys/kernel/debug/tracing/set_event_pid +echo 1 > /sys/kernel/debug/tracing/tracing_on ; sleep 2 ; echo 0 > /sys/kernel/debug/tracing/tracing_on +trace-cmd show diff --git a/src/06_optimization/trace/example2.sh b/src/06_optimization/trace/example2.sh new file mode 100644 index 0000000..158a565 --- /dev/null +++ b/src/06_optimization/trace/example2.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# 2. example +echo function_graph > /sys/kernel/debug/tracing/current_tracer +echo *i2c* > /sys/kernel/debug/tracing/set_ftrace_filter +echo 1 > /sys/kernel/debug/tracing/tracing_on +i2cdetect -y 0 +echo 0 > /sys/kernel/debug/tracing/tracing_on +trace-cmd show +echo nop > /sys/kernel/debug/tracing/current_tracer + diff --git a/src/06_optimization/trace/main.c b/src/06_optimization/trace/main.c new file mode 100644 index 0000000..1370ebd --- /dev/null +++ b/src/06_optimization/trace/main.c @@ -0,0 +1,8 @@ +#include + +int main() +{ + while(1) + sleep(1); + return 0; +} \ No newline at end of file diff --git a/src/06_optimization/trace/setup.sh b/src/06_optimization/trace/setup.sh new file mode 100644 index 0000000..c7a0e1b --- /dev/null +++ b/src/06_optimization/trace/setup.sh @@ -0,0 +1 @@ +mount -t debugfs nodev /sys/kernel/debug