Nothing
## ----setup, cache=FALSE, include=FALSE----------------------------------------
knitr::opts_chunk$set(collapse=TRUE, echo=TRUE, eval=FALSE)
# workaround for pkgdown
# https://github.com/r-lib/pkgdown/issues/1159#issuecomment-541356531
do.call(knitr::read_chunk, list("includes/5G-1.R"))
do.call(knitr::read_chunk, list("includes/5G-2.R"))
do.call(knitr::read_chunk, list("includes/5G-3.R"))
## ----1.configuration----------------------------------------------------------
# C <- 40e9 # link capacity [bps]
# rho <- 0.75 # utilization
#
# FH_EX <- (80 + 46) * 8 / C # avg. FH interarrival time [s]
# BH_bytes <- c(40, 576, 1500) # BH traffic distribution
# Weights <- c(7, 4, 1) / 12 #
# BH_EX <- sum(Weights * (8 * BH_bytes / C)) # avg. BH interarrival time [s]
#
# FH_w <- 0.5 # FH traffic ratio
# BH_w <- 1 - FH_w # BH traffic ratio
# FH_lambda <- FH_w * rho / FH_EX # FH avg. rate [pkts/s]
# BH_lambda <- BH_w * rho / BH_EX # BH avg. rate [pkts/s]
#
# Tsim <- 1e5 / (FH_lambda + BH_lambda) # simulation time
## ----1.simulation-------------------------------------------------------------
# library(simmer)
#
# set.seed(1234)
#
# # parametrized simulation function
# # - param[["n_switch"]] is the number of switches
# # - param[["fh_prio"]] is the priority level for FH traffic
# # - param[["preemptive"]] is the preemptiveness flag for switches
# simulate <- function(param) {
#
# # single FH traffic trajectory traversing n_switch elements sequentially
# fh_traffic <- lapply(1:param[["n_switch"]], function(i) {
# trajectory() %>%
# seize(paste0("switch", i)) %>%
# timeout(FH_EX) %>%
# release(paste0("switch", i))
# }) %>% join()
#
# # list of n_switch trajectories, one per element, modeling the interfering BH traffic
# bh_traffic <- lapply(1:param[["n_switch"]], function(i) {
# trajectory() %>%
# seize(paste0("switch", i)) %>%
# timeout(function() sample(BH_bytes*8/C, size=1, prob=Weights)) %>%
# release(paste0("switch", i))
# })
#
# # simulation environment
# env <- simmer() %>%
# # generator of FH traffic
# add_generator("FH_0_", fh_traffic, function() rexp(100, FH_lambda), priority=param[["fh_prio"]])
#
# for (i in 1:param[["n_switch"]])
# env %>%
# # n_switch resources, one per switch
# add_resource(paste0("switch", i), 1, Inf, mon=FALSE, preemptive=param[["preemptive"]]) %>%
# # n_switch generators of BH traffic
# add_generator(paste0("BH_", i, "_"), bh_traffic[[i]], function() rexp(100, BH_lambda))
#
# env %>%
# run(until=Tsim) %>%
# wrap()
# }
#
# # grid of scenarios
# cases <- expand.grid(n_switch = c(1, 2, 5),
# fh_prio = c(0, 1),
# preemptive = c(TRUE, FALSE))
#
# # parallel simulation
# system.time({
# envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate,
# mc.cores=nrow(cases), mc.set.seed=FALSE)
# })
## ----1.analysis---------------------------------------------------------------
# library(tidyverse)
#
# bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) {
# r <- quantile(x, probs=probs, na.rm=TRUE)
# names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
# r
# }
#
# arrivals <- envs %>%
# get_mon_arrivals() %>%
# left_join(rowid_to_column(cases, "replication")) %>%
# filter(!(fh_prio==0 & preemptive==TRUE)) %>%
# separate(name, c("Flow", "index", "n")) %>%
# mutate(total_time = end_time - start_time,
# waiting_time = total_time - activity_time,
# Queue = forcats::fct_recode(interaction(fh_prio, preemptive),
# "without SP" = "0.FALSE",
# "with SP" = "1.FALSE",
# "with SP & preemption" = "1.TRUE"))
#
# arrivals %>%
# filter(n_switch == 1) %>%
# # plot
# ggplot(aes(Queue, waiting_time*1e9, color=Flow)) + theme_bw() +
# stat_summary(fun.data=bp.vals, geom="boxplot", position="dodge") +
# theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) +
# labs(y = "Queueing Delay [ns]", x = element_blank())
#
# arrivals %>%
# filter(Flow == "FH") %>%
# # plot
# ggplot(aes(factor(n_switch), waiting_time*1e9, color=Queue)) + theme_bw() +
# stat_summary(fun.data=bp.vals, geom="boxplot", position="dodge") +
# theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) +
# labs(y = "Queueing Delay [ns]", x = "No. of switches")
## ----2.configuration----------------------------------------------------------
# C <- 1.25e9 # link capacity [bps]
# Tg <- 1e-6 # guard time [s]
#
# bytes <- c(40, 576, 1500) # traffic distribution
# Weights <- c(7, 4, 1) / 12 #
# EX <- sum(Weights * (8 * bytes / C)) # avg. interarrival time [s]
# burst <- 20 # burst length [pkts]
#
# ONU_lambda <- 20e6 / C / EX # avg. rate per ONU [pkts/s]
# SC_lambda <- 150e6 / C / EX # avg. rate for the SC [pkts/s]
# RRH_on <- 8 * 6000 / C # RRH on period [s]
# RRH_period <- RRH_on * C / 720e6 # RRH total period [s]
# RRH_off <- RRH_period - RRH_on # RRH off period [s]
## ----2.helpers----------------------------------------------------------------
# # helper function: round-robin-based selection of ONUs
# cyclic_counter <- function(n) {
# n <- as.numeric(n)
# i <- 1
# function(op) {
# if (!missing(op)) {
# i <<- i + op
# if (i > n) i <<- 1
# else if (i < 1) i <<- n
# }
# i
# }
# }
#
# # helper function: generator of packet sizes of n packets
# gen_pkts <- function(n) sample(bytes*8/C, size=n, prob=Weights, replace=TRUE)
#
# # helper function: double-exponential generator of interarrival times
# gen_exp <- function(lambda, burst) function()
# unlist(lapply(rexp(100/burst, lambda/burst), function(i) c(i, rep(0, rpois(1, burst)))))
## ----2.simulation-------------------------------------------------------------
# library(simmer)
#
# set.seed(1234)
#
# # parametrized simulation function
# # - param[["scenario"]] is the scenario identifier (A=small cell, B=RRH)
# # - param[["ONU_n"]] is the number of ONUs
# # - param[["limit"]] is the max. transmission window
# simulate <- function(param) {
#
# # global variables
# lambda <- rep(ONU_lambda, param[["ONU_n"]])
# limit <- rep(param[["limit"]], param[["ONU_n"]]) * 8 / C
# if (param[["scenario"]] == "A") {
# param[["ONU_n"]] <- param[["ONU_n"]] + 1
# lambda <- c(lambda, SC_lambda)
# limit <- c(limit, Inf)
# tx_t <- RRH_on + Tg + Tg * 0:param[["ONU_n"]]
# } else {
# Tg_n <- RRH_off %/% Tg - 1
# Tg_i <- rep(1:Tg_n, length.out=param[["ONU_n"]]+1)
# period_i <- rep(0:param[["ONU_n"]], each=Tg_n, length.out=param[["ONU_n"]]+1)
# tx_t <- RRH_on + RRH_period * period_i + Tg * Tg_i
# }
# eq_pkts <- rep(list(NULL), param[["ONU_n"]])
# tx_pkts <- rep(list(NULL), param[["ONU_n"]])
# t_head <- tail(tx_t, 1)
# onu_i <- cyclic_counter(param[["ONU_n"]])
# remaining <- Inf
#
# # DBA logic
# set_next_window <- function() {
# # time until the next RRH_on
# if (param[["scenario"]] == "B")
# remaining <- (t_head %/% RRH_period + 1) * RRH_period - t_head
# # generate new pkt lengths
# pkts <- get_queue_count(env, paste0("ONU", onu_i()))
# eq_pkts[[onu_i()]] <<- c(eq_pkts[[onu_i()]], gen_pkts(pkts - length(eq_pkts[[onu_i()]])))
# # reserve the next transmission window
# eq_cumsum <- cumsum(eq_pkts[[onu_i()]])
# n <- sum(eq_cumsum <= min(limit[[onu_i()]], remaining - Tg))
# if ((pkts && !n) || (remaining <= Tg)) {
# # go past the next RRH_on
# t_head <<- t_head + remaining + RRH_on + Tg
# n <- sum(eq_cumsum <= min(limit[[onu_i()]], RRH_off - 2*Tg))
# }
# tx_pkts[[onu_i()]] <<- head(eq_pkts[[onu_i()]], n)
# eq_pkts[[onu_i()]] <<- tail(eq_pkts[[onu_i()]], -n)
# tx_t[[onu_i()]] <<- t_head
# t_head <<- t_head + sum(tx_pkts[[onu_i()]]) + Tg
# index <<- 0
# tx_t[[onu_i(1)]] - now(env)
# }
#
# # list of ONU_n trajectories, one per ONU
# ONUs <- lapply(1:param[["ONU_n"]], function(i) {
# trajectory() %>%
# seize(paste0("ONU", i)) %>%
# set_capacity(paste0("ONU", i), 0) %>%
# seize("link") %>%
# timeout(function() {
# index <<- index + 1
# tx_pkts[[i]][index]
# }) %>%
# release("link") %>%
# release(paste0("ONU", i))
# })
#
# # OLT logic
# OLT <- trajectory() %>%
# simmer::select(function() paste0("ONU", onu_i())) %>%
# set_attribute("ONU", function() onu_i()) %>%
# set_capacity_selected(function() length(tx_pkts[[onu_i()]])) %>%
# timeout(function() sum(tx_pkts[[onu_i()]])) %>%
# timeout(set_next_window) %>%
# rollback(amount=6, times=Inf)
#
# # RRH logic
# RRH <- trajectory() %>%
# seize("link") %>%
# timeout(RRH_on) %>%
# release("link") %>%
# timeout(RRH_off) %>%
# rollback(amount=4, times=Inf)
#
# # simulation environment
# env <- simmer() %>%
# # the fiber link as a resource
# add_resource("link", 1, Inf)
#
# if (param[["scenario"]] == "B")
# # RRH worker
# env %>% add_generator("RRH_", RRH, at(0))
#
# for (i in 1:param[["ONU_n"]])
# env %>%
# # ONU_n resources, one per ONU
# add_resource(paste0("ONU", i), 0, Inf) %>%
# # ONU_n traffic generators, one per ONU
# add_generator(paste0("ONU_", i, "_"), ONUs[[i]], gen_exp(lambda[i], burst))
#
# env %>%
# # OLT worker
# add_generator("token_", OLT, at(RRH_on + Tg), mon=2) %>%
# run(until=1e5/sum(lambda)) %>%
# wrap()
# }
#
# # grid of scenarios
# cases <- data.frame(scenario = c(rep("A", 4), rep("B", 1)),
# ONU_n = c(rep(31, 4), rep(7, 1)),
# limit = c(Inf, 1500, 3000, 6000, Inf))
#
# # parallel simulation
# system.time({
# envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate,
# mc.cores=nrow(cases), mc.set.seed=FALSE)
# })
## ----2.analysis---------------------------------------------------------------
# library(tidyverse)
#
# bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) {
# r <- quantile(x, probs=probs, na.rm=TRUE)
# names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
# r
# }
#
# envs %>%
# get_mon_arrivals() %>%
# left_join(rowid_to_column(cases, "replication")) %>%
# mutate(scenario = forcats::fct_recode(
# scenario, `SmallCell + 31 ONUs`="A", `RRH + 7 ONUs`="B")) %>%
# separate(name, c("flow", "index", "n")) %>%
# mutate(flow = if_else(index == ONU_n+1, "SmallCell", flow)) %>%
# mutate(total_time = end_time - start_time,
# waiting_time = total_time - activity_time) %>%
# # plot
# ggplot(aes(forcats::fct_rev(flow), waiting_time*1e6, color=factor(limit))) + theme_bw() +
# facet_grid(~scenario, scales="free", space="free") +
# stat_summary(fun.data=bp.vals, geom="boxplot", position="dodge") +
# theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) +
# labs(y=expression(paste("Queueing Delay [", mu, "s]")), x=element_blank(), color="Limit [bytes]")
## ----3.configuration----------------------------------------------------------
# m <- 9 # number of RA retries
# Ps <- 0.03 # sleep power consumption [mW]
# Pi <- 10 # idle power consumption [mW]
# Prx <- 100 # rx power consumption [mW]
# Prbp <- 32.18 # tx power consumption per RB pair [mW]
# Ppre <- 32.18 # preamble tx power consumption [mW]
#
# Tbpre <- 0.0025 # time before preamble transmission [s]
# Tpre <- 0.0014 # time for preamble transmission [s]
# Trarx <- 0.01 # rx time to perform RA [s]
# Tcrcp <- 0.016 # sum of processing delays to establish a connection [s]
# Twait <- 0.054 # S1 processing and transfer delay [s]
#
# Brbp <- 36 # bytes per RB pair (QPSK modulation)
# Breq <- 7 # RRC request message size (bytes)
# Bcompcp <- 129 # RRC setup complete + NAS control plane SR + data for CP (bytes)
#
# Tra <- Tbpre + Trarx + Tpre
# Pra <- (Tbpre*Pi + Trarx*Prx + Tpre*Ppre) / Tra
# rbs <- (ceiling(Breq/Brbp) + ceiling(Bcompcp/Brbp)) * 1e-3
# Ttx <- Tcrcp + rbs + Twait
# Ptx <- (Tcrcp*Prx + rbs*Prbp + Twait*Prx) / Ttx
#
# tx_period <- 3600 # time between transmissions (seconds)
# Tsim <- 24*3600 # simulation time (seconds)
## ----3.simulation-------------------------------------------------------------
# library(simmer)
#
# set.seed(1234)
#
# # parametrized simulation function
# # - param[["meter_n"]] is the number of IoT devices in the cell
# # - param[["backoff"]] is the backoff time
# simulate <- function(param) {
#
# # identifiers for RA preambles
# preambles <- paste0("preamble_", 1:54)
#
# # IoT device logic
# meter <- trajectory() %>%
# trap("reading") %>%
# # sleep
# set_attribute("P", 0) %>%
# wait() %>%
# timeout(function() round(runif(1, 0, param[["backoff"]]), 3)) %>%
# # ra start
# simmer::select(preambles, policy="random") %>%
# seize_selected(
# continue=c(TRUE, TRUE),
# # ra & tx
# post.seize=trajectory() %>%
# set_attribute("P", Pra) %>%
# timeout(Tra) %>%
# release_selected() %>%
# set_attribute("P", Ptx) %>%
# timeout(Ttx),
# # ra & backoff & retry
# reject=trajectory() %>%
# set_attribute("P", Pra) %>%
# timeout(Tra) %>%
# set_attribute("P", Pi) %>%
# timeout(function() sample(1:20, 1) * 1e-3) %>%
# rollback(6, times=m)
# ) %>%
# rollback(5, times=Inf)
#
# # trigger a reading for all the meters every tx_period
# trigger <- trajectory() %>%
# timeout(tx_period) %>%
# send("reading") %>%
# rollback(2, times=Inf)
#
# # simulation environment
# env <- simmer() %>%
# # IoT device workers
# add_generator("meter_", meter, at(rep(0, param[["meter_n"]])), mon=2) %>%
# # trigger worker
# add_generator("trigger_", trigger, at(0), mon=0)
#
# for (i in preambles)
# # one resource per preamble
# env %>% add_resource(i, 1, 0, mon=FALSE)
#
# env %>%
# run(until=Tsim) %>%
# wrap()
# }
#
# # grid of scenarios
# cases <- expand.grid(meter_n = c(5e3, 1e4, 3e4), backoff = c(5, 10, 30, 60))
#
# # parallel simulation
# system.time({
# envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate,
# mc.cores=nrow(cases), mc.set.seed=FALSE)
# })
## ----3.analysis---------------------------------------------------------------
# library(tidyverse)
#
# bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) {
# r <- quantile(x, probs=probs, na.rm=TRUE)
# names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
# r
# }
#
# envs %>%
# get_mon_attributes() %>%
# group_by(replication, name) %>%
# summarise(dE = sum(c(0, head(value, -1) * diff(time)))) %>%
# left_join(rowid_to_column(cases, "replication")) %>%
# # plot
# ggplot(aes(factor(meter_n), dE*tx_period/Tsim, color=factor(backoff))) +
# stat_summary(fun.data=bp.vals, geom="boxplot", position="dodge") +
# theme_bw() + theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) +
# labs(y="Energy per Tx [mJ]", x="No. of devices", color="Backoff window [s]")
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.