Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmarks, logging #125

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions benchmark/benchmark.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,6 @@ Outlined benchmarks for developing an application using WebSockets (postponed):
choice of message size and buffers for long-running calculations which
connects to a server for distribution of results
=#
if !@isdefined(SRCPATH)
const SRCPATH = Base.source_dir() == nothing ? Pkg.dir("WebSockets", "benchmark") : Base.source_dir()
const LOGGINGPATH = realpath(joinpath(SRCPATH, "../logutils/"))
SRCPATH ∉ LOAD_PATH && push!(LOAD_PATH, SRCPATH)
LOGGINGPATH ∉ LOAD_PATH && push!(LOAD_PATH, LOGGINGPATH)
include(joinpath(SRCPATH, "functions_open_browsers.jl"))
end
# Don't run this if the output files are recent?
include("benchmark_prepare.jl")
# include detailed benchmarks using the results from the above as nominal.
# TODO include detailed benchmarks using the results from the above as nominal.
162 changes: 87 additions & 75 deletions benchmark/benchmark_prepare.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,36 @@
# Pull request welcome if someone can figure out how to do it.
# Running this file on a Windows laptop with all browsers takes 5-10 minutes.


if !isdefined(:SRCPATH)
const SRCPATH = Base.source_dir() == nothing ? Pkg.dir("WebSockets", "benchmark") : Base.source_dir()
const LOGGINGPATH = realpath(joinpath(SRCPATH, "../logutils/"))
SRCPATH ∉ LOAD_PATH && push!(LOAD_PATH, SRCPATH)
if !@isdefined LOGGINGPATH
(@__DIR__) ∉ LOAD_PATH && push!(LOAD_PATH, @__DIR__)
const LOGGINGPATH = realpath(joinpath(@__DIR__, "..", "logutils"))
LOGGINGPATH ∉ LOAD_PATH && push!(LOAD_PATH, LOGGINGPATH)
include(joinpath(SRCPATH, "functions_open_browsers.jl"))
end

include("functions_open_browsers.jl")
include("functions_benchmark.jl")

"A vector of message sizes"
const VSIZE = reverse([i^3 * 1020 for i = 1:12])
include(joinpath(SRCPATH, "functions_open_browsers.jl"))
include(joinpath(SRCPATH, "functions_benchmark.jl"))

#
prepareworker()
# Load modules on both processes
import HTTP
using WebSockets
import WebSockets: WebSocket
using ws_jce
using UnicodePlots
import IndexedTables.table
import ws_hts: listen_hts, getws_hts
import UnicodePlots: lineplot
using Dates
using Random
using Serialization
import Millboard.table
import ws_hts: listen_hts,
getws_hts,
close_hts
using logutils_ws

#
remotecall_fetch(ws_jce.clog, 2, "ws_jce ", :green, " is ready")
# Start async HTS server on this process and check that it is up and running
const TIMEOUT = Base.Dates.Second(20)
const TIMEOUT = Second(20)
hts_task = start_hts(TIMEOUT)

"""
Expand All @@ -50,8 +53,7 @@ Prepare logging for this process
"""
const ID = "Benchmark"
const LOGFILE = "benchmark_prepare.log"
import logutils_ws: logto, clog, zlog, zflush, clog_notime
fbm = open(joinpath(SRCPATH, "logs", LOGFILE), "w")
global fbm = open(joinpath(@__DIR__, "logs", LOGFILE), "w")
logto(fbm)
clog(ID, "Started async HTS and prepared parallel worker")
zflush()
Expand All @@ -64,18 +66,19 @@ zflush()
const INITSIZE = 130560
const INITN = 200


# Measured time interval vectors [ns]
# Time measurements are taken directly both at server and client
(testid, serverlatencies, clientlatencies) = HTS_JCE(INITN, INITSIZE)
global testid, serverlatencies, clientlatencies = HTS_JCE(INITN, INITSIZE)
# Calculate speeds [ns/b] and averaged speeds (bandwidths)
(serverspeeds, clientspeeds,
serverbandwidth, clientbandwidth) = serverandclientspeeds(INITSIZE, serverlatencies, clientlatencies)
global serverspeeds, clientspeeds,
serverbandwidth, clientbandwidth = serverandclientspeeds(INITSIZE, serverlatencies, clientlatencies)
# Store plots and a table in dictionaries
vars= [:serverspeeds, :clientspeeds];
init_plots = Dict(testid => lp(vars, testid));
init_tables = Dict(testid => table(eval.(vars)..., names = vars));
init_serverbandwidths = Dict(testid => serverbandwidth);
init_clientbandwidths = Dict(testid => clientbandwidth);
global vars= [:serverspeeds, :clientspeeds]
global init_plots = Dict(testid => lp(vars, testid));
global init_tables = Dict(testid => tabulate(vars));
global init_serverbandwidths = Dict(testid => serverbandwidth);
global init_clientbandwidths = Dict(testid => clientbandwidth);
# Sleep to avoid interspersing with worker output to REPL
sleep(2)
# Brief output to file and console
Expand All @@ -88,38 +91,40 @@ clog(testid, " Initial test run with messagesize ", INITSIZE, " bytes \n\t",
#

COUNTBROWSER.value = 0
serverbandwidth = 0.
clientbandwidth = 0.
serverbandwidths = Vector{Float64}()
clientbandwidths = Vector{Float64}()
t1 = Vector{Int}()
t2 = Vector{Int}()
t3 = Vector{Int}()
t4 = Vector{Int}()
browser = ""
success = true
while success
global serverbandwidth = 0.
global clientbandwidth = 0.
global serverbandwidths = Vector{Float64}()
global clientbandwidths = Vector{Float64}()
global t1 = Vector{Int}()
global t2 = Vector{Int}()
global t3 = Vector{Int}()
global t4 = Vector{Int}()
global browser = ""
global alright = true
while alright
# Measured time interval vectors [ns] for the next browser in line
# Time measurements are taken only at server; a message pattern
# is used to distinguish server and client performance
(browser, t1, t2, t3, t4) = HTS_BCE(INITN, INITSIZE)
global browser, t1, t2, t3, t4 = HTS_BCE(INITN, INITSIZE)
if browser != ""
# Calculate speeds [ns/b] and averaged speeds (bandwidths)
(serverspeeds, clientspeeds,
serverbandwidth, clientbandwidth) =
serverspeeds, clientspeeds,
serverbandwidth, clientbandwidth =
serverandclientspeeds_indirect(INITSIZE, t1, t2, t3, t4)
# Store plots and a table in dictionaries
testid = "HTS_BCE " * browser
push!(init_plots, testid => lp(vars, testid));
push!(init_tables, testid => table(eval.(vars)..., names = vars));
#push!(init_tables, testid => table(eval.(vars)..., names = vars));
push!(init_tables, testid => tabulate(vars));

push!(init_serverbandwidths, testid => serverbandwidth);
push!(init_clientbandwidths, testid => clientbandwidth);
# Brief output to file and console
clog(testid, " Initial test run with messagesize ", INITSIZE, " bytes \n\t",
"serverbandwidth = ", :yellow, round(serverbandwidth, digits=4), :normal, " [ns/b] = [s/GB]\n\t",
:normal, "clientbandwidth = ", :yellow, round(clientbandwidth, digits=4), :normal, " [ns/b] = [s/GB]")
else
success = false
alright = false
end
end

Expand Down Expand Up @@ -155,17 +160,17 @@ end
#
for msgsiz in VSIZE
COUNTBROWSER.value = 0
t1 = Vector{Int}()
t2 = Vector{Int}()
t3 = Vector{Int}()
t4 = Vector{Int}()
browser = ""
success = true
while success
global t1 = Vector{Int}()
global t2 = Vector{Int}()
global t3 = Vector{Int}()
global t4 = Vector{Int}()
global browser = ""
global alright = true
while alright
# Measured time interval vectors [ns] for the next browser in line
# Time measurements are taken only at server; a message pattern
# is used to distinguish server and client performance
(browser, t1, t2, t3, t4) = HTS_BCE(SAMPLES, msgsiz)
global browser, t1, t2, t3, t4 = HTS_BCE(SAMPLES, msgsiz)
testid = "HTS_BCE " * browser
if browser != ""
# Find averaged speed (bandwidth) scalars
Expand All @@ -179,7 +184,7 @@ for msgsiz in VSIZE
push!(serverbandwidths[testid], sbw)
push!(clientbandwidths[testid], cbw)
else
success = false
alright = false
end
end
end
Expand All @@ -189,11 +194,11 @@ end
#
# Measurements are done. Close server and log file, open results log file.
#
ws_hts.close_hts()
close_hts()
clog(ID, "Closing HTS server")
const RESULTFILE = "benchmark_results.log"
clog(ID, "Results are summarized in ", joinpath(SRCPATH, "logs", RESULTFILE))
fbmr = open(joinpath(SRCPATH, "logs", RESULTFILE), "w")
clog(ID, "Results are summarized in ", joinpath(@__DIR__, "logs", RESULTFILE))
fbmr = open(joinpath(@__DIR__, "logs", RESULTFILE), "w")
logto(fbmr)
close(fbm)

Expand All @@ -203,22 +208,22 @@ close(fbm)
# Find optimum message size and nominal 100% bandwidths
# Make and store plots and tables
#
test_bestserverbandwidths = Dict{String, Float64}()
test_bestclientbandwidths = Dict{String, Float64}()
test_bestserverlatencies = Dict{String, Float64}()
test_bestclientlatencies = Dict{String, Float64}()
test_plots = Dict()
test_tables = Dict()
test_latency_plots = Dict()
test_latency_tables = Dict()
serverbandwidth = Vector{Float64}()
clientbandwidth = Vector{Float64}()
serverlatency = Vector{Float64}()
clientlatency = Vector{Float64}()
bestserverbandwidth = 0.
bestclientbandwidth = 0.
bestserverlatency = 0.
bestclientlatency = 0.
global test_bestserverbandwidths = Dict{String, Float64}()
global test_bestclientbandwidths = Dict{String, Float64}()
global test_bestserverlatencies = Dict{String, Float64}()
global test_bestclientlatencies = Dict{String, Float64}()
global test_plots = Dict()
global test_tables = Dict()
global test_latency_plots = Dict()
global test_latency_tables = Dict()
global serverbandwidth = Vector{Float64}()
global clientbandwidth = Vector{Float64}()
global serverlatency = Vector{Float64}()
global clientlatency = Vector{Float64}()
global bestserverbandwidth = 0.
global bestclientbandwidth = 0.
global bestserverlatency = 0.
global bestclientlatency = 0.

for testid in keys(serverbandwidths)
serverbandwidth = serverbandwidths[testid]
Expand All @@ -232,7 +237,8 @@ for testid in keys(serverbandwidths)
vars = [:serverbandwidth, :clientbandwidth]
tvars = vcat([:VSIZE], vars)
push!(test_plots, testid => lp([:VSIZE, :VSIZE], vars, testid));
push!(test_tables, testid => table(eval.(tvars)..., names = tvars));
push!(test_tables, testid => tabulate(tvars));

# Store msgsiz-latency line plots and tables in dictionaries
serverlatency = serverbandwidth .* VSIZE
clientlatency = clientbandwidth .* VSIZE
Expand All @@ -243,18 +249,24 @@ for testid in keys(serverbandwidths)
vars = [:serverlatency, :clientlatency]
tvars = vcat([:VSIZE], vars)
push!(test_latency_plots, testid => lp([:VSIZE, :VSIZE], vars, testid));
push!(test_latency_tables, testid => table(eval.(tvars)..., names = tvars));
push!(test_latency_tables, testid => tabulate(tvars));

# Brief output to file and console






clog_notime(testid, :normal, " Varying message size: \n\t",
"bestserverbandwidth = ", :yellow, round(bestserverbandwidth, digits=4), :normal, " [ns/b] = [s/GB]",
" @ size = ", VSIZE[findfirst(serverbandwidth, bestserverbandwidth)], " b\n\t",
" @ size = ", VSIZE[firstmatch(serverbandwidth, bestserverbandwidth)], " b\n\t",
:normal, "bestclientbandwidth = ", :yellow, round(bestclientbandwidth, digits=4), :normal, " [ns/b] = [s/GB]",
" @ size = ", VSIZE[findfirst(clientbandwidth, bestclientbandwidth)], " b\n\t",
" @ size = ", VSIZE[firstmatch(clientbandwidth, bestclientbandwidth)], " b\n\t",
"bestserverlatency = ", :yellow, Int(round(bestserverlatency)), :normal, " [ns] ",
" @ size = ", VSIZE[findfirst(serverlatency, bestserverlatency)], " b\n\t",
" @ size = ", VSIZE[firstmatch(serverlatency, bestserverlatency)], " b\n\t",
:normal, "bestclientlatency = ", :yellow, Int(round(bestclientlatency)), :normal, " [ns]",
" @ size = ", VSIZE[findfirst(clientlatency, bestclientlatency)], " b\n\t"
" @ size = ", VSIZE[firstmatch(clientlatency, bestclientlatency)], " b\n\t"
)
end

Expand Down
35 changes: 27 additions & 8 deletions benchmark/functions_benchmark.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
# Included in benchmark.jl
# Included in benchmark_prepare.jl
using Distributed
using Dates
import Random: seed!
import Millboard.table
import UnicodePlots: lineplot,
AsciiCanvas,
title,
title!,
xlabel!
import ws_hts: listen_hts,
TCPREF,
getws_hts
import WebSockets: readguarded,
write,
WebSocket
tabulate(vars) = table(hcat(eval.(vars)...), colnames = string.(vars))

firstmatch(coll, value) = something(findfirst(isequal(value), coll), 0)



"Adds process 2, same LOAD_PATH as process 1"
function prepareworker()
# Prepare worker
Expand All @@ -17,11 +36,11 @@ end

"Start and wait for async hts server"
function start_hts(timeout)
hts_task = @async ws_hts.listen_hts()
hts_task = @async listen_hts()
t1 = now() + timeout
while now() < t1
sleep(0.5)
isdefined(ws_hts.TCPREF, :x) && break
isdefined(TCPREF, :x) && break
end
if now()>= t1
msg = " did not establish server before timeout "
Expand Down Expand Up @@ -49,7 +68,7 @@ function get_hts_jce()
t1 = now() + TIMEOUT
while now() < t1
yield()
hts = ws_hts.getws_hts()
hts = getws_hts()
isa(hts, WebSocket) && break
sleep(0.5)
end
Expand All @@ -75,7 +94,7 @@ function get_hts_bce()
t1 = now() + TIMEOUT
while now() < t1
yield()
hts = ws_hts.getws_hts()
hts = getws_hts()
isa(hts, WebSocket) && break
sleep(0.5)
end
Expand All @@ -102,7 +121,7 @@ function HTS_JCE(n, messagesize)
end
clog(id, hts)
# Random seeding, same for all samples
srand(1)
seed!(1)
clog(id, "Sending ", n, " messages of ", messagesize , " random bytes")
sendtime = Int64(0)
receivereplytime = Int64(0)
Expand Down Expand Up @@ -166,7 +185,7 @@ function HTS_BCE(n, x)
end
clog(id, hts)
# Random seeding, same for all samples
srand(1)
seed!(1)
clog(id, "Sending ", n, " messages of ", x , " random bytes")
st1 = UInt64(0)
st2 = UInt64(0)
Expand Down Expand Up @@ -300,4 +319,4 @@ end
function sp(syx::Symbol, syy::Symbol)
spl = scatterplot(eval(syx), eval(syy), title = String(syy), width = displaysize(stdout)[2]-15, canvas = DotCanvas)
xlabel!(spl, String(syx))
end
end
Loading