From cdc9404739cec84843bc96031e957041d19608a6 Mon Sep 17 00:00:00 2001 From: Sam Moore Date: Mon, 19 Aug 2013 12:27:52 +0800 Subject: [PATCH] Add data performance tests, revise block diagram, add pthread_mutex_init --- reports/week3/block_diagram.png | Bin 0 -> 63917 bytes reports/week3/block_diagram.svg | 698 ++++++++++++++++++++++++ server/sensor.c | 2 + testing/data_performance/Makefile | 27 + testing/data_performance/README | 3 + testing/data_performance/binfile.c | 56 ++ testing/data_performance/csv.c | 61 +++ testing/data_performance/main.c | 55 ++ testing/data_performance/plot.py | 44 ++ testing/data_performance/sqlite.c | 65 +++ testing/data_performance/storespeed.png | Bin 0 -> 22756 bytes 11 files changed, 1011 insertions(+) create mode 100644 reports/week3/block_diagram.png create mode 100644 reports/week3/block_diagram.svg create mode 100644 testing/data_performance/Makefile create mode 100644 testing/data_performance/README create mode 100644 testing/data_performance/binfile.c create mode 100644 testing/data_performance/csv.c create mode 100644 testing/data_performance/main.c create mode 100755 testing/data_performance/plot.py create mode 100644 testing/data_performance/sqlite.c create mode 100644 testing/data_performance/storespeed.png diff --git a/reports/week3/block_diagram.png b/reports/week3/block_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..379a485cb03c04791212b7b57de9723f3cd0cc9b GIT binary patch literal 63917 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

E)Eeb^>H5Cf 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 b8y8nmpD4MYMeW)U@FVw1S-R|n@yGuUHri7X literal 0 HcmV?d00001 diff --git a/reports/week3/block_diagram.svg b/reports/week3/block_diagram.svg new file mode 100644 index 0000000..8bbe47a --- /dev/null +++ b/reports/week3/block_diagram.svg @@ -0,0 +1,698 @@ + + + + + + + + + + image/svg+xml + + + + + + + "High level" Server(Beaglebone / RPi) + + + Read Analogue InputWrite Digital Output + + LEGENDHardware (Implementation)Software (Implementation)Existing software can be used + + + Image Processing(OpenCV) + + + + Video Cameras + + + + + Networking(Wireless Chip, Wired connection) + OS provided TCP/IP + + + + Remote Client(PC or laptop controlled by user) + Client side scripting (JavaScript) + web browser + + + + Server control API (FastCGI) + webserver installed in OS (nginx) + + + + + Actuators + + + ADC, DAC, Digital I/O + + + + + OS provided drivers (if we're lucky) + + + Existing OS (GNU/Linux) + + + USB + + + + + + + + + + + + Electronics, Amplification + + + + + Sensors + + Pneumatics + + + + + + + + + Multithreaded server with watchdog (pthreads for C) + + Data collection & transfer + (sensors: binary/CSV/sqlite)(actuators: single value, PID control) + + + + + Data Storage(USB Harddrive) + + + + + diff --git a/server/sensor.c b/server/sensor.c index b746134..83ffaaa 100644 --- a/server/sensor.c +++ b/server/sensor.c @@ -70,6 +70,8 @@ void Sensor_Init(Sensor * s, int id) { Fatal("Too many sensors! FILENAMESIZE is %d; increase it and recompile.", FILENAMESIZE); } + + pthread_mutex_init(&(s->mutex), NULL); sprintf(filename, "%d", s->id); unlink(filename); //TODO: Move old files somewhere diff --git a/testing/data_performance/Makefile b/testing/data_performance/Makefile new file mode 100644 index 0000000..d938c99 --- /dev/null +++ b/testing/data_performance/Makefile @@ -0,0 +1,27 @@ +# Makefile for rpi side server +CXX = gcc +FLAGS = -std=c99 -Wall -Werror -pedantic -g +LIB = -lpthread -lsqlite3 +BIN = binfile csv sqlite +RM = rm -f + + + +all : $(BIN) + +% : %.c + $(CXX) $(FLAGS) -o $@ $< $(LIB) + + + +clean : + $(RM) $(BIN) + $(RM) *.o + +clean_full: #cleans up all backup files + $(RM) $(BIN) $(OBJ) $(LINKOBJ) + $(RM) *.*~ + $(RM) *~ + + + diff --git a/testing/data_performance/README b/testing/data_performance/README new file mode 100644 index 0000000..ac48a8f --- /dev/null +++ b/testing/data_performance/README @@ -0,0 +1,3 @@ +A few tests of performance for different methods of storing/transferring sensor data. +The important thing to remember is that the data is stored and accessed sequentially. +A database, whilst a useful thing and definitely capable of being used for this, is probably overkill. diff --git a/testing/data_performance/binfile.c b/testing/data_performance/binfile.c new file mode 100644 index 0000000..aae8ea2 --- /dev/null +++ b/testing/data_performance/binfile.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +typedef struct +{ + float time; + float value; +} DataPoint; + + + + +int main(int argc, char ** argv) +{ + assert(argc == 3); + + int bufsiz = atoi(argv[1]); + int numpoints = atoi(argv[2]); + assert(bufsiz > 0); + DataPoint * buffer = (DataPoint*)(calloc(bufsiz, sizeof(DataPoint))); + + + + FILE * file = fopen("data.bin", "wb"); + + struct timeval start_time; + gettimeofday(&start_time, NULL); + + int i = 0; + while (i < numpoints) + { + int j = 0; + for (j = 0; j < bufsiz && i < numpoints; ++j) + { + buffer[j].time = i; + buffer[j].value = i; + + } + i += j; + assert(fwrite(buffer, sizeof(DataPoint), j, file) == j); + + + } + + struct timeval end_time; + gettimeofday(&end_time, NULL); + + + fclose(file); + free(buffer); + float time_elapsed = (float)(end_time.tv_sec - start_time.tv_sec) + 1e-6*(end_time.tv_usec - start_time.tv_usec); + printf("%f\n", time_elapsed); + return 0; +} diff --git a/testing/data_performance/csv.c b/testing/data_performance/csv.c new file mode 100644 index 0000000..3a8155f --- /dev/null +++ b/testing/data_performance/csv.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +typedef struct +{ + float time; + float value; +} DataPoint; + + + + +int main(int argc, char ** argv) +{ + assert(argc == 3); + + int bufsiz = atoi(argv[1]); + int numpoints = atoi(argv[2]); + assert(bufsiz > 0); + DataPoint * buffer = (DataPoint*)(calloc(bufsiz, sizeof(DataPoint))); + + + FILE * file = fopen("data.csv", "w"); + + struct timeval start_time; + gettimeofday(&start_time, NULL); + + + int i = 0; + while (i < numpoints) + { + int j = 0; + for (j = 0; j < bufsiz && i < numpoints; ++j) + { + buffer[j].time = i; + buffer[j].value = i; + + } + i += j; + + for (int k = 0; k < j; ++k) + { + fprintf(file, "%f,%f\n", buffer[i].time, buffer[i].value); + } + } + + + + struct timeval end_time; + gettimeofday(&end_time, NULL); + + + fclose(file); + + free(buffer); + float time_elapsed = (float)(end_time.tv_sec - start_time.tv_sec) + 1e-6*(end_time.tv_usec - start_time.tv_usec); + printf("%f\n", time_elapsed); + return 0; +} diff --git a/testing/data_performance/main.c b/testing/data_performance/main.c new file mode 100644 index 0000000..4485875 --- /dev/null +++ b/testing/data_performance/main.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +typedef struct +{ + float time; + float value; +} DataPoint; + + + + +int main(int argc, char ** argv) +{ + assert(argc == 3); + + int bufsiz = atoi(argv[1]); + int numpoints = atoi(argv[2]); + assert(bufsiz > 0); + DataPoint * buffer = (DataPoint*)(calloc(bufsiz, sizeof(DataPoint))); + + struct timeval start_time; + gettimeofday(&start_time, NULL); + + FILE * file = fopen("data.bin", "wb"); + + int i = 0; + while (i < numpoints) + { + int j = 0; + for (j = 0; j < bufsiz && i < numpoints; ++j) + { + buffer[j].time = i; + buffer[j].value = i; + + } + i += j; + assert(fwrite(buffer, sizeof(DataPoint), j, file) == j); + + + } + + fclose(file); + + + struct timeval end_time; + gettimeofday(&end_time, NULL); + + free(buffer); + float time_elapsed = (float)(end_time.tv_sec - start_time.tv_sec) + 1e-6*(end_time.tv_usec - start_time.tv_usec); + printf("%f\n", time_elapsed); + return 0; +} diff --git a/testing/data_performance/plot.py b/testing/data_performance/plot.py new file mode 100755 index 0000000..90e4d6b --- /dev/null +++ b/testing/data_performance/plot.py @@ -0,0 +1,44 @@ +#!/usr/bin/python + +import sys +import os +import Gnuplot +import subprocess +import numpy + +methods = ["sqlite", "csv", "binfile"] +data = {} +averages = 100 +g = Gnuplot.Gnuplot() + + +for program in methods: + data.update({program : []}) + + numpoints = 1 + while (numpoints < 10000): + bufsiz = 1 + while (bufsiz < 2): + + run = ["./"+program, str(bufsiz), str(numpoints)] + times = [] + for i in xrange(averages): + p = subprocess.Popen(run, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + times.append(float(p.stdout.readline().strip(" \r\n"))) + + times = numpy.array(times) + data[program].append([numpoints,bufsiz,numpy.mean(times), numpy.std(times)]) + + bufsiz *= 10 + numpoints += 100 + + g("set xlabel \"Data Points\"") + g("set ylabel \"Total Time (s)\"") + g("set title \"Time to Store Data Points\"") + g.replot(Gnuplot.Data(data[program], title=program, with_="lp",using="1:3")) + +print "Done!" +sys.stdin.readline() + + + diff --git a/testing/data_performance/sqlite.c b/testing/data_performance/sqlite.c new file mode 100644 index 0000000..b0ffb36 --- /dev/null +++ b/testing/data_performance/sqlite.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +typedef struct +{ + float time; + float value; +} DataPoint; + + + + +int main(int argc, char ** argv) +{ + assert(argc == 3); + + int bufsiz = atoi(argv[1]); + int numpoints = atoi(argv[2]); + assert(bufsiz > 0); + DataPoint * buffer = (DataPoint*)(calloc(bufsiz, sizeof(DataPoint))); + + + + sqlite3 * db; + sqlite3_open("sqlite.db", &db); + + + char query[BUFSIZ]; + char * query_value = query+sprintf(query,"insert into sensor values("); + + + struct timeval start_time; + gettimeofday(&start_time, NULL); + + int i = 0; + while (i < numpoints) + { + int j = 0; + for (j = 0; j < bufsiz && i < numpoints; ++j) + { + buffer[j].time = i; + buffer[j].value = i; + + } + i += j; + for (int k = 0; k < j; ++k) + { + sprintf(query_value,"%f,%f)", buffer[k].time, buffer[k].value); + sqlite3_exec(db, query, NULL, NULL, NULL); + } + } + + struct timeval end_time; + gettimeofday(&end_time, NULL); + + + sqlite3_close(db); + free(buffer); + float time_elapsed = (float)(end_time.tv_sec - start_time.tv_sec) + 1e-6*(end_time.tv_usec - start_time.tv_usec); + printf("%f\n", time_elapsed); + return 0; +} diff --git a/testing/data_performance/storespeed.png b/testing/data_performance/storespeed.png new file mode 100644 index 0000000000000000000000000000000000000000..3f50e42c513aa4db9dfdca271e8db1865503cdce GIT binary patch literal 22756 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