diff --git a/src/05-optimization/Makefile b/src/05-optimization/Makefile new file mode 100644 index 0000000..23c1094 --- /dev/null +++ b/src/05-optimization/Makefile @@ -0,0 +1,5 @@ +DIRS=$(filter-out Makefile, $(wildcard *)) + +all clean install clean_all: + for dir in $(DIRS); do $(MAKE) $@ -C $$dir; done + diff --git a/src/05-optimization/clock/Makefile b/src/05-optimization/clock/Makefile new file mode 100644 index 0000000..8d0e0e8 --- /dev/null +++ b/src/05-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/05-optimization/clock/clock.c b/src/05-optimization/clock/clock.c new file mode 100644 index 0000000..ca46040 --- /dev/null +++ b/src/05-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 t_basic.txt + +dump_opti: $(EXEC_OPTI) + $(OBJDUMP) -dS $(EXEC_OPTI) > t_opti.txt + +# Inclusion des dépendances générées par l'option -MD +-include $(OBJS_BASIC:.o=.d) $(OBJS_OPTI:.o=.d) + +.PHONY: all basic opti clean clean_all dump_basic dump_opti \ No newline at end of file diff --git a/src/05-optimization/ex02/Makefile b/src/05-optimization/ex02/Makefile new file mode 100644 index 0000000..d043773 --- /dev/null +++ b/src/05-optimization/ex02/Makefile @@ -0,0 +1,54 @@ +EXE=ex2 +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 -fno-omit-frame-pointer +##CFLAGS+=-O2 +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/05-optimization/ex02/main.c b/src/05-optimization/ex02/main.c new file mode 100644 index 0000000..08db720 --- /dev/null +++ b/src/05-optimization/ex02/main.c @@ -0,0 +1,24 @@ +#include +#include + +#define SIZE 65536 + +int main() +{ + // generate data + short data[SIZE]; + for (int i = 0; i < SIZE; i++) { + data[i] = rand() % 512; + } + + + long long sum = 0; + for (int j = 0; j < 10000; j++) { + for (int i = 0; i < SIZE; i++) { + if (data[i] >= 256) { + sum += data[i]; + } + } + } + printf ("sum=%lld\n", sum); +} diff --git a/src/05-optimization/ex03/ApacheAccessLogAnalyzer.cpp b/src/05-optimization/ex03/ApacheAccessLogAnalyzer.cpp new file mode 100644 index 0000000..50047e8 --- /dev/null +++ b/src/05-optimization/ex03/ApacheAccessLogAnalyzer.cpp @@ -0,0 +1,37 @@ +#include "ApacheAccessLogAnalyzer.h" + +#include +#include +#include + + +ApacheAccessLogAnalyzer::ApacheAccessLogAnalyzer(std::string filename) + : myFilename(filename) +{ + +} + +void ApacheAccessLogAnalyzer::openFile() +{ + myInFile.open(myFilename.c_str()); +} + +void ApacheAccessLogAnalyzer::closeFile() +{ + myInFile.close(); +} + +void ApacheAccessLogAnalyzer::processFile() +{ + std::cout << "Processing log file " << myFilename << std::endl; + for( std::string line; getline( myInFile, line ); ) + { + // parse the log line to extract the hostname / ip address + int space_pos = line.find_first_of(" "); + std::string hostname = line.substr(0, space_pos); + + myHostCounter.notifyHost(hostname); + } + + std::cout << "Found " << myHostCounter.getNbOfHosts() << " unique Hosts/IPs" << std::endl; +} diff --git a/src/05-optimization/ex03/ApacheAccessLogAnalyzer.h b/src/05-optimization/ex03/ApacheAccessLogAnalyzer.h new file mode 100644 index 0000000..28a25cd --- /dev/null +++ b/src/05-optimization/ex03/ApacheAccessLogAnalyzer.h @@ -0,0 +1,20 @@ +#include "HostCounter.h" + +#include +#include +#include + +class ApacheAccessLogAnalyzer +{ + public: + ApacheAccessLogAnalyzer(std::string filename); + + void openFile(); + void closeFile(); + void processFile(); + + private: + std::string myFilename; + std::ifstream myInFile; + HostCounter myHostCounter; +}; diff --git a/src/05-optimization/ex03/HostCounter.cpp b/src/05-optimization/ex03/HostCounter.cpp new file mode 100644 index 0000000..99a5d5b --- /dev/null +++ b/src/05-optimization/ex03/HostCounter.cpp @@ -0,0 +1,26 @@ +#include "HostCounter.h" + +#include // for std::find + +HostCounter::HostCounter() +{ +} + +bool HostCounter::isNewHost(std::string hostname) +{ + return std::find(myHosts.begin(), myHosts.end(), hostname) == myHosts.end(); +} + +void HostCounter::notifyHost(std::string hostname) +{ + // add the host in the list if not already in + if(isNewHost(hostname)) + { + myHosts.push_back(hostname); + } +} + +int HostCounter::getNbOfHosts() +{ + return myHosts.size(); +} diff --git a/src/05-optimization/ex03/HostCounter.h b/src/05-optimization/ex03/HostCounter.h new file mode 100644 index 0000000..d627d02 --- /dev/null +++ b/src/05-optimization/ex03/HostCounter.h @@ -0,0 +1,22 @@ +#include + +#include + +class HostCounter +{ + public: + HostCounter(); + + // Announce a host to the HostCounter. + // if the host is new, it will be added to the list, otherwise we ignore it. + void notifyHost(std::string hostname); + + // return the number of unique hosts found so far + int getNbOfHosts(); + + private: + // check if host is already in the list + bool isNewHost(std::string hostname); + + std::vector< std::string > myHosts; +}; diff --git a/src/05-optimization/ex03/Makefile b/src/05-optimization/ex03/Makefile new file mode 100644 index 0000000..a511b48 --- /dev/null +++ b/src/05-optimization/ex03/Makefile @@ -0,0 +1,30 @@ +##CXX?=g++ +##CXXFLAGS=-Wall -Wextra -g -O0 -MD + +TOOLCHAIN_PATH=/buildroot/output/host/usr/bin/ +TOOLCHAIN=$(TOOLCHAIN_PATH)aarch64-linux- +CXX=$(TOOLCHAIN)g++ +CXXFLAGS=-Wall -Wextra -g -gdwarf -O0 -MD -mcpu=cortex-a53 -fno-omit-frame-pointer -funwind-tables + +SOURCES=$(wildcard *.cpp) +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE=read-apache-logs + +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) + +.c.o: + $(CXX) -c $(CXXFLAGS) $< -o $@ + + +clean: + @rm -f $(OBJECTS) + @rm -f *.d *~ + +clean_all: clean + @rm -f $(EXECUTABLE) + @rm -f perf.data perf.data.old + +-include *.d diff --git a/src/05-optimization/ex03/main.cpp b/src/05-optimization/ex03/main.cpp new file mode 100644 index 0000000..f74cc0f --- /dev/null +++ b/src/05-optimization/ex03/main.cpp @@ -0,0 +1,30 @@ +#include "ApacheAccessLogAnalyzer.h" + +#include + +// forward declaration +void usage(const char* progName); + +int main(int argc, const char* argv[]) +{ + if(argc != 2) + { + usage(argv[0]); + return -1; + } + + std::string filename = argv[1]; + + ApacheAccessLogAnalyzer analyzer(filename); + + analyzer.openFile(); + analyzer.processFile(); + analyzer.closeFile(); +} + + +void usage(const char* progName) +{ + std::cout << "Usage: " << progName << " " << std::endl; + std::cout << "\nWhere is the apache access log file" << std::endl; +} diff --git a/src/05-optimization/gcov/Makefile b/src/05-optimization/gcov/Makefile new file mode 100644 index 0000000..dc3f70d --- /dev/null +++ b/src/05-optimization/gcov/Makefile @@ -0,0 +1,34 @@ +CC?=gcc +CFLAGS=-std=c11 -Wall -g -fprofile-arcs -ftest-coverage +SOURCES=$(wildcard *.c) +OBJECTS=$(SOURCES:.c=.o) +EXECUTABLE=example-gcov + +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 *.gcno *.gcda *.gcov + + +gcov-generate: all + ./$(EXECUTABLE) + gcov main.c + +gcov-read: gcov-generate + less main.c.gcov + + +-include *.d diff --git a/src/05-optimization/gcov/main.c b/src/05-optimization/gcov/main.c new file mode 100644 index 0000000..4c39b85 --- /dev/null +++ b/src/05-optimization/gcov/main.c @@ -0,0 +1,19 @@ +#include + +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/05-optimization/gpio/Makefile b/src/05-optimization/gpio/Makefile new file mode 100644 index 0000000..274aa5c --- /dev/null +++ b/src/05-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/05-optimization/gpio/gpio.c b/src/05-optimization/gpio/gpio.c new file mode 100644 index 0000000..1266fbf --- /dev/null +++ b/src/05-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/05-optimization/gprof/Makefile b/src/05-optimization/gprof/Makefile new file mode 100644 index 0000000..ea6dc2d --- /dev/null +++ b/src/05-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/05-optimization/gprof/main.c b/src/05-optimization/gprof/main.c new file mode 100644 index 0000000..a4cd546 --- /dev/null +++ b/src/05-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/05-optimization/gprof/target.mk b/src/05-optimization/gprof/target.mk new file mode 100644 index 0000000..65ac0c7 --- /dev/null +++ b/src/05-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/05-optimization/mmio/Makefile b/src/05-optimization/mmio/Makefile new file mode 100644 index 0000000..fcf2ee0 --- /dev/null +++ b/src/05-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/05-optimization/mmio/mmio.c b/src/05-optimization/mmio/mmio.c new file mode 100644 index 0000000..7268e49 --- /dev/null +++ b/src/05-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/05-optimization/trace/Makefile b/src/05-optimization/trace/Makefile new file mode 100644 index 0000000..451b10f --- /dev/null +++ b/src/05-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/05-optimization/trace/example1.sh b/src/05-optimization/trace/example1.sh new file mode 100644 index 0000000..24fa81d --- /dev/null +++ b/src/05-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/05-optimization/trace/example2.sh b/src/05-optimization/trace/example2.sh new file mode 100644 index 0000000..158a565 --- /dev/null +++ b/src/05-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/05-optimization/trace/main.c b/src/05-optimization/trace/main.c new file mode 100644 index 0000000..1370ebd --- /dev/null +++ b/src/05-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/05-optimization/trace/setup.sh b/src/05-optimization/trace/setup.sh new file mode 100644 index 0000000..c7a0e1b --- /dev/null +++ b/src/05-optimization/trace/setup.sh @@ -0,0 +1 @@ +mount -t debugfs nodev /sys/kernel/debug