commit 2f1837a75e96612040c6db2b594adf7463173c88 Author: Loïc Guégan Date: Tue Apr 1 17:56:32 2025 +0200 Cleaning repository diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b637a67 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.csv binary \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5904657 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +netstats.txt \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a3ed07 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# ina260-beaglebone-performance + +## Notes +- Host machine = the one that launches the experiments + +## Package requirements +### Host machine *AND* BeagleBone Black +Packages: +- time +- iperf +- zeromq +### BeagleBone Black +Driver: +- INA260 for BeagleBone Black (available [here](https://gitlab.com/manzerbredes/ina260-sysfs-driver)) + +## Results used in the paper +- The results presented in the paper can be downloaded [here](https://data.lguegan.com/Repeatability/Datasets/INA260_BeagleBone_Black.tar.gz). +- You can analyze them by extracting the content of the archive into the `analysis/results/` folder, and run the `analysis/analyze.R` script. diff --git a/analysis/analyze.R b/analysis/analyze.R new file mode 100644 index 0000000..745b9d3 --- /dev/null +++ b/analysis/analyze.R @@ -0,0 +1,177 @@ +library("tidyverse") +library("latex2exp") + +## |--------------------------------+---------------------+-------------+------------------------------+--------------------------------------------+------------------------------------------------------------------| +## | Monitored Hardware | Alim | I2C Address | Notes | OS | sha256sum (.img file) | +## |--------------------------------+---------------------+-------------+------------------------------+--------------------------------------------+------------------------------------------------------------------| +## | 1Kohm resistor | some random 5V alim | 0x40 | | | | +## | Raspberry Pi 3 model B (2016) | 5.1V rpi alim | 0x41 | Powered through GPIO 2 and 6 | 2023-05-03-raspios-bullseye-arm64-lite.img | 9cd68ff450bc0fe0ac5b60e32723bc403ebca89d1214714e8e74361370d25204 | +## | Raspberry Pi 3 model B+ (2017) | 5.1V rpi alim | 0x42 | Powered through GPIO 2 and 6 | 2023-05-03-raspios-bullseye-arm64-lite.img | 9cd68ff450bc0fe0ac5b60e32723bc403ebca89d1214714e8e74361370d25204 | +## | Raspberry Pi 4 model B (2018) | 5.1V rpi alim | 0x43 | Powered through GPIO 2 and 6 | 2023-05-03-raspios-bullseye-arm64-lite.img | 9cd68ff450bc0fe0ac5b60e32723bc403ebca89d1214714e8e74361370d25204 | +## |--------------------------------+---------------------+-------------+------------------------------+--------------------------------------------+------------------------------------------------------------------| + + +pure_read=read_csv("results/pure_read.csv") +zmq=read_csv("results/zmq.csv") + +GG_DELAY_READ=function(exp,for_inmem=0){ + delays=exp%>%filter(inmem==for_inmem)%>%group_by(usen,deviceid)%>%mutate(tsnsec=(nsecs*10e-10)+timestamp) + delays=delays%>%mutate(delay=tsnsec-lag(tsnsec,1,default=NA))%>%filter(!is.na(delay))%>%mutate(time=timestamp-startat) + delays=delays%>%group_by(usen)%>%mutate(duration=max(time)) + delays=delays%>%group_by(usen,deviceid,time)%>%summarize(delay_sd=sd(delay),delay_mean=mean(delay),duration=mean(duration),delay_max=max(delay),delay_min=min(delay)) +##### Store in file + f=paste0("figures/delay_inmem",for_inmem,"_stddev.txt") + window=0 + ina1<<-delays%>%filter(usen==1,time>window,time%filter(usen==2,time>window,time%filter(usen==3,time>window,time%filter(usen==4,time>window,time%filter(inmem==for_inmem)%>%mutate(time=timestamp-startat) + data=exp%>%group_by(usen,deviceid)%>%group_by(usen,deviceid,timestamp,startat,endat)%>%summarize(nperdev=n())%>%mutate(time=timestamp-startat,duration=endat-startat) +##### Now complete missing measurements (say no value on at time 5 then a row with a zero at that time must be added) + data=data%>%group_by(usen,deviceid)%>%complete(timestamp=seq(min(startat),min(endat),by=1),fill=list(nperdev=0))%>%mutate(startat=min(startat,na.rm=TRUE),endat=max(startat,na.rm=TRUE),time=timestamp-startat,duration=max(duration,na.rm=TRUE)) +##### Compute additional metrics + durations=exp%>%group_by(usen,deviceid)%>%summarise(duration=max(endat)-max(startat)) + med=data%>%group_by(usen)%>%summarize(median=round(median(nperdev)),duration=mean(duration)) +#### End + + # Plot + msg=paste0("(inmem=",for_inmem,")") + nread=max(exp$nread) + label_at <- function(n) function(x) ifelse(x %% n == 0, x, ifelse (x==0,x,"")) + ggplot(data,aes(x=time,y=nperdev,color=deviceid)) + geom_point(size=0.3) +geom_line() + xlab("Time (s)") + ylab(TeX(r'(Sample read frequency $f_r$)')) + + facet_wrap(~usen,labeller = labeller(usen = c("1" = "With 1 ina260 in use", + "2" = "With 2 ina260 in use", + "3" = "With 3 ina260 in use", + "4" = "With 4 ina260 in use")))+ + scale_x_continuous(breaks = seq(0,3600,by=60),labels=label_at(60))+ + scale_y_continuous(breaks = seq(0, max(data$nperdev), by = 1000),expand = expansion(mult = 0.1))+ + #ggtitle(paste("Stop until",nread,"measurements are done", msg))+ + labs(color="Device id")+ + geom_vline(data=durations,aes(xintercept=duration,color=deviceid),linetype="dashed",show.legend = FALSE)+ + geom_hline(data=med,aes(yintercept=median),show.legend = FALSE,size=0.3)+ + geom_text(data=med,aes(x=duration/2,y=median,label=median),inherit.aes=FALSE,vjust=-0.55)+ + theme(legend.position="top",legend.margin=margin(b = -0.2, unit='cm')) + ggsave(paste0("figures/pure_read_inmem",for_inmem!=0,".pdf"),width=6,height=5.5) +} + +TABLE_DELAY=function(exp,for_inmem=0){ + delays=exp%>%filter(inmem==for_inmem)%>%group_by(usen,deviceid)%>%mutate(tsnsec=(nsecs*10e-10)+timestamp) + delays=delays%>%group_by(usen,deviceid)%>%mutate(delay=tsnsec-lag(tsnsec,1,default=NA))%>%filter(!is.na(delay))%>%mutate(time=timestamp-startat) + f=paste0("figures/fp_inmem",for_inmem,".txt") + write("", f) + delays%>%group_by(usen)%>%group_walk(function(data,grp){ + cur_usen=grp$usen + cdf=ecdf(data$delay) # Get CDF +#### For fd + fdefault=454.54 + percent=1-cdf(1/fdefault) + write(paste0("inmem=",for_inmem," usen=",cur_usen,": f=",fdefault,"Hz percent=",round(percent*100,digits=2),"%", " missings=",percent*length(data$delay)),f, append=TRUE) +#### For fmax + fmax=3571.429 + percent=1-cdf(1/fmax) + write(paste0("inmem=",for_inmem," usen=",cur_usen,": f=",fmax,"Hz percent=",round(percent*100,digits=2),"%", " missings=",percent*length(data$delay),"\n----"),f, append=TRUE) + # plot(cdf,xlim=c(0,0.001)) + }) +} + +GG_READ_POWER=function(exp,for_inmem=0){ + # Analyze + exp=exp%>%filter(inmem==for_inmem)%>%mutate(time=timestamp-startat+nsecs*1e-9) + nread=max(exp$nread) + msg=paste0("(inmem=",for_inmem,")") + data=exp%>%group_by(usen,deviceid)%>%mutate(duration=endat-startat) + # Plot + label_at <- function(n) function(x) ifelse(x %% n == 0, x, ifelse (x==0,x,"")) + ggplot(data,aes(x=time,y=power,color=deviceid)) + geom_point(size=0.3) +geom_line() + xlab("Time (s)") + ylab("Power consumption (W)") + + facet_wrap(~usen,labeller = labeller(usen = c("1" = "With 1 ina260 in use", + "2" = "With 2 ina260 in use", + "3" = "With 3 ina260 in use", + "4" = "With 4 ina260 in use")))+ + scale_x_continuous(breaks = seq(0,3600,by=60),labels=label_at(60)) + ggtitle(paste("Stop until",nread,"measurements are done", msg)) + ggsave(paste0("figures/pure_read_inmem",for_inmem!=0,"_power.pdf"),width=10) +} + +TABLE_READ_POWER=function(exp){ + power_0x40<<-median((exp%>%filter(addr=="0x40"))$power) + power_0x41<<-median((exp%>%filter(addr=="0x41"))$power) + power_0x42<<-median((exp%>%filter(addr=="0x42"))$power) + power_0x43<<-median((exp%>%filter(addr=="0x43"))$power) + power_0x40_std<<-round(sd((exp%>%filter(addr=="0x40"))$power),digits=2) + power_0x41_std<<-round(sd((exp%>%filter(addr=="0x41"))$power),digits=2) + power_0x42_std<<-round(sd((exp%>%filter(addr=="0x42"))$power),digits=2) + power_0x43_std<<-round(sd((exp%>%filter(addr=="0x43"))$power),digits=2) + f="figures/power_median.txt" + write(paste0("1Kohm resistor 0x40: ",power_0x40,"W(",power_0x40_std,")"), f) + write(paste0("Raspberri Pi 3 model B (2016) 0x41: ",power_0x41,"W(",power_0x41_std,")"), f, append=TRUE) + write(paste0("Raspberri Pi 3 model B+ (2017) 0x42: ",power_0x42,"W(",power_0x42_std,")"), f, append=TRUE) + write(paste0("Raspberry Pi 4 model B (2018) 0x43: ",power_0x43,"W(",power_0x43_std,")"), f, append=TRUE) +} + +GG_ZMQ_PERF=function(exp){ +##### Analyze + data=exp%>%group_by(usen,deviceid,timestamp)%>%summarize(nperdev=n(),duration=max(duration))%>%mutate(time=timestamp-min(timestamp)) + data=data%>%group_by(usen,deviceid)%>%mutate(startat=min(timestamp),endat=max(timestamp)) + jean <<- data +##### Now complete missing measurements (say no value on at time 5 then a row with a zero at that time must be added) + data=data%>%group_by(usen,deviceid)%>%complete(timestamp=seq(min(startat),min(startat)+max(duration),by=1),fill=list(nperdev=0))%>%mutate(startat=min(startat,na.rm=TRUE),endat=max(startat,na.rm=TRUE),time=timestamp-startat) +#### Now compute additional metrics + med=data%>%group_by(usen)%>%summarize(median=round(median(nperdev)),duration_real=max(timestamp)-min(timestamp)) +#### Plot + label_at <- function(n) function(x) ifelse(x %% n == 0, x, ifelse (x==0,x,"")) + ggplot(data,aes(x=time,y=nperdev,color=deviceid))+geom_point()+geom_line()+ + facet_wrap(~usen,labeller = labeller(usen = c("1" = "With 1 ina260 in use", + "2" = "With 2 ina260 in use", + "3" = "With 3 ina260 in use", + "4" = "With 4 ina260 in use")))+ + scale_x_continuous(breaks = seq(0,3600,by=60),labels=label_at(60))+ + scale_y_continuous(breaks = seq(0, max(data$nperdev), by = 1000),expand = expansion(mult = 0.1))+ + geom_hline(data=med,aes(yintercept=median),show.legend = FALSE,size=0.3)+ + geom_text(data=med,aes(x=duration_real/2,y=median,label=median),inherit.aes=FALSE,vjust=-0.55)+ + #ggtitle(paste("Running zmq experiment for",unique(exp$duration),"s"))+ + labs(color="Device id")+ + xlab("Time (s)") + ylab(TeX(r'(Sample read frequency $f_r$)'))+ + theme(legend.position="top",legend.margin=margin(b = -0.2, unit='cm')) + ggsave("figures/zmq.pdf") + +} + + +TABLE_DELAY(pure_read,0) +TABLE_DELAY(pure_read,1) +GG_DELAY_READ(pure_read,0) +GG_DELAY_READ(pure_read,1) +GG_READ_POWER(pure_read,0) +GG_READ_POWER(pure_read,1) +GG_READ_PERF(pure_read,0) +GG_READ_PERF(pure_read,1) +GG_ZMQ_PERF(zmq) +TABLE_READ_POWER(pure_read) diff --git a/analysis/figures/delay_inmem0_stddev.txt b/analysis/figures/delay_inmem0_stddev.txt new file mode 100644 index 0000000..06a2402 --- /dev/null +++ b/analysis/figures/delay_inmem0_stddev.txt @@ -0,0 +1,4 @@ +With 1 INA260 sd=6.00937815261358e-05 min=0.000136256217956543 max=0.00356734121167982 +With 2 INA260 sd=0.000115172896629317 min=0.000216300670917218 max=0.00428919131939228 +With 3 INA260 sd=9.35477242715891e-05 min=0.000364981953750181 max=0.00227669163433182 +With 4 INA260 sd=0.000116468101100906 min=0.000549188091275403 max=0.00281525927986728 diff --git a/analysis/figures/delay_inmem1_stddev.txt b/analysis/figures/delay_inmem1_stddev.txt new file mode 100644 index 0000000..23d4013 --- /dev/null +++ b/analysis/figures/delay_inmem1_stddev.txt @@ -0,0 +1,4 @@ +With 1 INA260 sd=1.73904637611061e-05 min=0.000125433459426417 max=0.000961011106317694 +With 2 INA260 sd=2.3209413244053e-05 min=0.000202646191488176 max=0.000837534866076988 +With 3 INA260 sd=3.46769061118768e-05 min=0.000362649877020653 max=0.00108031448743022 +With 4 INA260 sd=3.55985545001392e-05 min=0.000521048997183266 max=0.00118109433905883 diff --git a/analysis/figures/fp_inmem0.txt b/analysis/figures/fp_inmem0.txt new file mode 100644 index 0000000..a13652d --- /dev/null +++ b/analysis/figures/fp_inmem0.txt @@ -0,0 +1,13 @@ + +inmem=0 usen=1: f=454.54Hz percent=0.01% missings=28.99999999999 +inmem=0 usen=1: f=3571.429Hz percent=1.31% missings=6553.00000000003 +---- +inmem=0 usen=2: f=454.54Hz percent=0.01% missings=144.99999999995 +inmem=0 usen=2: f=3571.429Hz percent=95.62% missings=956231 +---- +inmem=0 usen=3: f=454.54Hz percent=0.04% missings=604.999999999978 +inmem=0 usen=3: f=3571.429Hz percent=99.06% missings=1485850 +---- +inmem=0 usen=4: f=454.54Hz percent=0.07% missings=1470 +inmem=0 usen=4: f=3571.429Hz percent=99.39% missings=1987883 +---- diff --git a/analysis/figures/fp_inmem1.txt b/analysis/figures/fp_inmem1.txt new file mode 100644 index 0000000..d86a5b6 --- /dev/null +++ b/analysis/figures/fp_inmem1.txt @@ -0,0 +1,13 @@ + +inmem=1 usen=1: f=454.54Hz percent=0% missings=17.0000000000018 +inmem=1 usen=1: f=3571.429Hz percent=0.07% missings=364.999999999992 +---- +inmem=1 usen=2: f=454.54Hz percent=0% missings=33.000000000023 +inmem=1 usen=2: f=3571.429Hz percent=99.04% missings=990429 +---- +inmem=1 usen=3: f=454.54Hz percent=0.02% missings=225.999999999981 +inmem=1 usen=3: f=3571.429Hz percent=99.6% missings=1494044 +---- +inmem=1 usen=4: f=454.54Hz percent=0.03% missings=571.000000000086 +inmem=1 usen=4: f=3571.429Hz percent=99.85% missings=1996963 +---- diff --git a/analysis/figures/power_median.txt b/analysis/figures/power_median.txt new file mode 100644 index 0000000..3fc1ab7 --- /dev/null +++ b/analysis/figures/power_median.txt @@ -0,0 +1,4 @@ +1Kohm resistor 0x40: 0.3W(0.05) +Raspberri Pi 3 model B (2016) 0x41: 1.34W(0.02) +Raspberri Pi 3 model B+ (2017) 0x42: 2.27W(0.02) +Raspberry Pi 4 model B (2018) 0x43: 1.91W(0.15) diff --git a/analysis/figures/pure_read_inmemFALSE.pdf b/analysis/figures/pure_read_inmemFALSE.pdf new file mode 100644 index 0000000..ae182ad Binary files /dev/null and b/analysis/figures/pure_read_inmemFALSE.pdf differ diff --git a/analysis/figures/pure_read_inmemFALSE_delay.pdf b/analysis/figures/pure_read_inmemFALSE_delay.pdf new file mode 100644 index 0000000..fd1f70f Binary files /dev/null and b/analysis/figures/pure_read_inmemFALSE_delay.pdf differ diff --git a/analysis/figures/pure_read_inmemFALSE_power.pdf b/analysis/figures/pure_read_inmemFALSE_power.pdf new file mode 100644 index 0000000..41d5009 Binary files /dev/null and b/analysis/figures/pure_read_inmemFALSE_power.pdf differ diff --git a/analysis/figures/pure_read_inmemTRUE.pdf b/analysis/figures/pure_read_inmemTRUE.pdf new file mode 100644 index 0000000..6468f20 Binary files /dev/null and b/analysis/figures/pure_read_inmemTRUE.pdf differ diff --git a/analysis/figures/pure_read_inmemTRUE_delay.pdf b/analysis/figures/pure_read_inmemTRUE_delay.pdf new file mode 100644 index 0000000..00dcf8a Binary files /dev/null and b/analysis/figures/pure_read_inmemTRUE_delay.pdf differ diff --git a/analysis/figures/pure_read_inmemTRUE_power.pdf b/analysis/figures/pure_read_inmemTRUE_power.pdf new file mode 100644 index 0000000..353cba8 Binary files /dev/null and b/analysis/figures/pure_read_inmemTRUE_power.pdf differ diff --git a/analysis/figures/zmq.pdf b/analysis/figures/zmq.pdf new file mode 100644 index 0000000..2825548 Binary files /dev/null and b/analysis/figures/zmq.pdf differ diff --git a/sandbox/.gitignore b/sandbox/.gitignore new file mode 100644 index 0000000..841d798 --- /dev/null +++ b/sandbox/.gitignore @@ -0,0 +1,2 @@ +ina260-zmq-publisher +pure-read/read \ No newline at end of file diff --git a/sandbox/config b/sandbox/config new file mode 100644 index 0000000..317165f --- /dev/null +++ b/sandbox/config @@ -0,0 +1,19 @@ +# Global Configuration: +inadev="2:0x40 2:0x41 2:0x42 2:0x43" +bbhost=debian@192.168.6.2 +delaypurezmq=10 +delayiperfpure=10 + +# Pure Read Experiments: +nread=500000 +readrest=60 + +# ZMQ Experiments: +zmqrest=60 +zmqduration=300 +hostip=192.168.7.1 +zmqport=5556 +zmqlogdelay=0 +zmqloginterval=60 +zmqmsgsize=20242880 +zmqmaxqueue=1 diff --git a/sandbox/config_beaglebone b/sandbox/config_beaglebone new file mode 100644 index 0000000..317165f --- /dev/null +++ b/sandbox/config_beaglebone @@ -0,0 +1,19 @@ +# Global Configuration: +inadev="2:0x40 2:0x41 2:0x42 2:0x43" +bbhost=debian@192.168.6.2 +delaypurezmq=10 +delayiperfpure=10 + +# Pure Read Experiments: +nread=500000 +readrest=60 + +# ZMQ Experiments: +zmqrest=60 +zmqduration=300 +hostip=192.168.7.1 +zmqport=5556 +zmqlogdelay=0 +zmqloginterval=60 +zmqmsgsize=20242880 +zmqmaxqueue=1 diff --git a/sandbox/config_rpi b/sandbox/config_rpi new file mode 100644 index 0000000..376065a --- /dev/null +++ b/sandbox/config_rpi @@ -0,0 +1,19 @@ +# Global Configuration: +inadev="1:0x41" +bbhost=pi@10.128.0.93 +delaypurezmq=0 +delayiperfpure=5 + +# Pure Read Experiments: +nread=500000 +readrest=5 + +# ZMQ Experiments: +zmqrest=5 +zmqduration=60 +hostip=10.128.0.133 +zmqport=5556 +zmqlogdelay=0 +zmqloginterval=10 +zmqmsgsize=20242880 +zmqmaxqueue=1 \ No newline at end of file diff --git a/sandbox/pure-read/Makefile b/sandbox/pure-read/Makefile new file mode 100644 index 0000000..353835b --- /dev/null +++ b/sandbox/pure-read/Makefile @@ -0,0 +1,10 @@ + +all: read + +read: read.c + gcc $^ -o $@ + +clean: + - rm read + +.PHONY: clean \ No newline at end of file diff --git a/sandbox/pure-read/read.c b/sandbox/pure-read/read.c new file mode 100644 index 0000000..539933d --- /dev/null +++ b/sandbox/pure-read/read.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 255 +#define IN_MEM (inmem!=0) + +typedef struct power_data { + float power; // Power value + long ts; // Associated timestamp + long nsecs; // Associated nanosecs +} power_data; + +int main(int argc, char *argv[]) +{ + if(argc != 4){ + printf("Usage: %s \n\ + \rFor , see folder name in /sys/kernel/ina260/",argv[0]); + exit(1); + } + + char *deviceid=argv[1]; + int nread=atoi(argv[2]); + int inmem=atoi(argv[3]); + + if(nread<=0){ + printf(" must be greater than 0\n"); + exit(3); + } + + // File to read + char path[255]; + sprintf(path, "/sys/kernel/ina260/%s/power", deviceid); + + // Open file + int fd; + char buff[BUFFER_SIZE]; + fd = open(path, O_RDONLY); + if(fd<0){ + perror(path); + exit(2); + } + + // Check if its in memory reading + power_data *data; + if(IN_MEM){ + data=malloc(sizeof(power_data)*nread); + if(data == NULL){ + perror("Cannot allocate enough memory for in memory reads"); + exit(4); + } + } + + // Perform reads + float power=-1; + struct timespec power_ts; + clock_gettime(CLOCK_REALTIME, &power_ts); + + printf("startat:%ld\n", power_ts.tv_sec); + for(int i=0;i Power is %fW\n",deviceid, power_ts.tv_sec,power_ts.tv_nsec,power); + } + lseek(fd,0,SEEK_SET); + } + close(fd); + + if(IN_MEM){ + // We only print now (most I/O will happend at the end and this must be visible on the results) + for(int i=0;i Power is %fW\n",deviceid, data[i].ts, data[i].nsecs, data[i].power); + } + free(data); + } + printf("endat:%ld\n", time(NULL)); + return 0; +} diff --git a/sandbox/run_beaglebone.sh b/sandbox/run_beaglebone.sh new file mode 100755 index 0000000..c610c6e --- /dev/null +++ b/sandbox/run_beaglebone.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +set -e + +wai=$(dirname $(readlink -f "$0")) # Current script directory +source ${wai}/config + +info () { + echo -e "\033[0;32m$@\033[0m" +} + +abort () { + echo -e "\033[0;31m$@\033[0m" + exit 1 +} + +iperf-run () { + info "---------- Running iperf test ----------" + iperf -c ${hostip} +} + +pure-read () { + local clean="${1:-1}" + local inmem="${2:-0}" + info "---------- Running pure read experiments (inmem=${inmem},clean=${clean}) ----------" + info "Ensuring that ina260 devices are connected..." + for dev in $inadev + do + bus=$(echo $dev|cut -d: -f1) + addr=$(echo $dev|cut -d: -f2) + [ -z $(ls /sys/kernel/ina260/ |grep "${bus}-.*${addr#0x}") ] && echo ina260 $addr | sudo tee "/sys/bus/i2c/devices/i2c-${bus}/new_device" + [ -z $(ls /sys/kernel/ina260/ |grep "${bus}-.*${addr#0x}") ] && abort "Cannot connect $dev" + done + info "Compiling..." + make -C ${wai}/pure-read -B + [ $clean -eq 1 ] && rm -f ${wai}/pure_read_bus*.out + local ndev=$(echo $inadev|wc -w) + for usen in $(seq 1 $ndev) + do + info "Run $nread read over $usen devices" + local n=0 + unset pids # Erase previous pids + for dev in $inadev + do + local bus=$(echo $dev|cut -d: -f1) + local addr=$(echo $dev|cut -d: -f2) + local devicepath=$(realpath /sys/kernel/ina260/${bus}-*${addr#0x}) + local deviceid=$(basename ${devicepath}) + local logfile=${wai}/pure_read_bus${bus}_addr${addr}_usen${usen}_nread${nread}_inmem${inmem}.out + echo "${bus}:${addr}:${usen}:${nread}:${deviceid}" > ${logfile} + /usr/bin/time -f "statsline:%P:%M" ${wai}/pure-read/read $deviceid $nread $inmem &>> ${logfile} & + pids[${i}]=$! + n=$(( n + 1 )) + [ $n -eq $usen ] && break + done + # Wait for all pids + for pid in ${pids[*]}; do + wait $pid + done + sync # Ensure that I/O are applied on sdcard + info "Beaglebone is resting for ${readrest}s" + sleep ${readrest} + done + # Generate the results + info "Collecting logs..." + local csv="${wai}/pure_read.csv" + [ $clean -eq 1 ] && echo "bus,addr,usen,nread,deviceid,startat,endat,inmem,cpu_usage,resident,timestamp,nsecs,power" > "$csv" + for logfile in ${wai}/pure_read_bus*inmem${inmem}.out + do + local bus=$(head -n1 "$logfile"|cut -d: -f1) + local addr=$(head -n1 "$logfile"|cut -d: -f2) + local usen=$(head -n1 "$logfile"|cut -d: -f3) + local nread=$(head -n1 "$logfile"|cut -d: -f4) + local deviceid="${bus}-${addr}" + local startat=$(cat "$logfile"|grep startat|cut -d: -f2) + local endat=$(cat "$logfile"|grep endat|cut -d: -f2) + local cpu_usage=$(cat "$logfile"|grep statsline|cut -d: -f2|awk '{print(($0+0)/100)}') + local resident=$(cat "$logfile"|grep statsline|cut -d: -f3|awk '{print(($0+0)*1000)}') + local infos="${bus},${addr},${usen},${nread},${deviceid},${startat},${endat},${inmem},${cpu_usage},${resident}" + awk '/Power is/ { print("'${infos}',"$2+0","$3+0","$6+0)}' "$logfile" >> "$csv" + done +} + +zmq () { + echo "---------- Running zmq experiments ----------" + info "Disconnecting all ina260..." + for dev in $(ls /sys/kernel/ina260/) + do + dev=$(basename $dev) + bus=$(echo $dev|cut -d\- -f1) + addr=$(echo $dev|cut -d\- -f2) + echo 0x${addr} | sudo tee /sys/bus/i2c/devices/i2c-${bus}/delete_device + done + # Setup publisher + cd ${wai}/ina260-zmq-publisher + rm -f publisher_*.log + info "Compiling..." + make -B + # Run experiments (add one new ina260 at each loop) + local n=1 + for dev in $inadev + do + info "Run zmq over $n devices for ${zmqduration}s" + bus=$(echo $dev|cut -d: -f1) + addr=$(echo $dev|cut -d: -f2) + [ -z $(ls /sys/kernel/ina260/ |grep "${bus}-.*${addr#0x}") ] && echo ina260 $addr | sudo tee "/sys/bus/i2c/devices/i2c-${bus}/new_device" + [ -z $(ls /sys/kernel/ina260/ |grep "${bus}-.*${addr#0x}") ] && abort "Cannot connect $dev" + # Run experiment + sed "s/^KEY=.*/KEY=usen$n/g" -i config.mk + make publish & + sleep ${zmqduration} + kill -s SIGINT $(cat pid) + # Wait for all publisher processes to end: + for pid in $(cat pid) + do + while ps -p $pid > /dev/null; do continue; done + done + # Done + n=$(( n + 1 )) + info "Beaglebone is resting for ${zmqrest}s" + sleep $zmqrest + done + cd ${wai} # Go back to last directory +} + +##### Run experiments +# Network benchmark +iperf-run +info "Sleep ${delayiperfpure}s before starting pure-read experiments..." +sleep ${delayiperfpure} +# Pure read +pure-read 1 1 # Do in memory first! +pure-read 0 0 # This way, we are sure in file has no impact +# Sleep +info "Sleep ${delaypurezmq}s before starting zmq experiments..." +sleep ${delaypurezmq} +# ZMQ +zmq \ No newline at end of file diff --git a/sandbox/run_host.sh b/sandbox/run_host.sh new file mode 100755 index 0000000..c107d4b --- /dev/null +++ b/sandbox/run_host.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +set -e +wai=$(dirname $(readlink -f "$0")) # Current script directory +zmq=${wai}/ina260-zmq-publisher +source ${wai}/config # Load experiment configuration +bbexec="ssh -q ${bbhost}" +nosync="no" # change this to yes ONLY FOR TESTS + +# Ensure zmq publisher is available +[ ! -d "${zmq}" ] && git clone https://gitlab.com/manzerbredes/ina260-zmq-publisher.git "${zmq}" +# Configuring zmq project +echo "Configuring ina260-zmq-publisher" +sed "s/^SUBSCRIBER_ADDR=.*/SUBSCRIBER_ADDR=${hostip}/g" -i ${zmq}/config.mk +sed "s/^ZMQ_PORT=.*/ZMQ_PORT=${zmqport}/g" -i ${zmq}/config.mk +sed "s/^LOG_DELAY=.*/LOG_DELAY=${zmqlogdelay}/g" -i ${zmq}/config.mk +sed "s/^LOG_INTERVAL=.*/LOG_INTERVAL=${zmqloginterval}/g" -i ${zmq}/config.mk +sed "s/^ZMQ_MSG_SIZE=.*/ZMQ_MSG_SIZE=${zmqmsgsize}/g" -i ${zmq}/config.mk +sed "s/^MAX_QUEUE=.*/MAX_QUEUE=${zmqmaxqueue}/g" -i ${zmq}/config.mk + +# Setting up beaglebone +[ ${nosync} != "yes" ] && rsync -avh --exclude=".git*" --exclude="ina260-zmq-publisher/data" ina260-zmq-publisher pure-read run_beaglebone.sh config ${bbhost}:sandbox/ + +# Cleaning previous results +[ -x "${zmq}/data" ] && rm -rf "${zmq}/data" + +##### Run experiments +# Start zmq subscriber on the host +echo "Starting subscriber" +cd $zmq +make -B +make subscribe & +zmqpid=$! +cd - > /dev/null +# Start iperf +iperf -s -fm -o netstats.txt & +iperfpid=$! +# Start experiments +$bbexec "cd sandbox && ./run_beaglebone.sh" + +# Collect pure-read results +echo "Fetching pure-read results" +rsync -avh ${bbhost}:sandbox/pure_read.csv ${wai}/../analysis/results/ + +# Collect zmq results +echo "Formatting zmq results" +. ${wai}/config +zmqcsv="${wai}/../analysis/results/zmq.csv" +echo "bus,addr,deviceid,usen,duration,loginterval,logdelay,rest,msgsize,timestamp,nsecs,power" > "$zmqcsv" +for exp in ${zmq}/data/* +do + usen=$(basename $exp|sed "s/usen//g") + for dev in $exp/* + do + deviceid=$(basename $dev) + bus=$(echo $deviceid|cut -d\- -f1) + addr=0x$(echo $deviceid|cut -d\- -f2|awk '{print $0+0}') + infos="${bus},${addr},${bus}-${addr},${usen},${zmqduration},${zmqloginterval},${zmqlogdelay},${zmqrest},${zmqmsgsize}" + cat $dev/* | awk '!/timestamp/{print("'$infos',"$0)}' >> "$zmqcsv" + done +done + +# Collecting iperf results +echo "Formatting iperf results" +bw=$(cat netstats.txt |awk -F '[ -]+' '/sec/{print $8}') # Mbps +iperfcsv="${wai}/../analysis/results/iperf.csv" +echo "bw" > "$iperfcsv" +echo "${bw}" >> "$iperfcsv" + +# Stopping zmq subscriber and iperf +echo "Stopping subscriber..." +kill $zmqpid +echo "Stopping iperf..." +kill $iperfpid +echo "Finished congratulations!" diff --git a/scripts/network_beaglebone.sh b/scripts/network_beaglebone.sh new file mode 100644 index 0000000..11fdce4 --- /dev/null +++ b/scripts/network_beaglebone.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Config +NAMESERVER="162.19.75.102" + +# Setup +ifconfig eth0 down +ifconfig usb1 down +ifconfig usb0 10.0.0.2/24 +iptables -F +ip route del default +ip route add default via 10.0.0.1 dev usb0 +echo "nameserver ${NAMESERVER}" > /etc/resolv.conf diff --git a/scripts/network_host.sh b/scripts/network_host.sh new file mode 100644 index 0000000..d48b90b --- /dev/null +++ b/scripts/network_host.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Config +INTERNET_INTERFACE="wlp0s20f3" +BEAGLEBONE_INTERFACE="enp0s20f0u4u4u2" + +# Setup +iptables -F +iptables -t nat -A POSTROUTING -o ${INTERNET_INTERFACE} -j MASQUERADE +iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +iptables -A FORWARD -i ${BEAGLEBONE_INTERFACE} -o ${INTERNET_INTERFACE} -j ACCEPT