Commit 5e0ce1f5 by FritzFlorian

Add plots to context switch benchmarks.

parent e2092e63
Pipeline #1383 failed with stages
in 38 seconds
...@@ -11,7 +11,7 @@ __fiber_continue: ...@@ -11,7 +11,7 @@ __fiber_continue:
* r0 = continuation that returned control back to the caller (null if fallthrough) * r0 = continuation that returned control back to the caller (null if fallthrough)
* *
* Variables * Variables
* r4 = temporary for the old stack pointer */ * r1 = temporary for the old stack pointer */
/* ========== Save State ========== */ /* ========== Save State ========== */
/* store programm counter for later return */ /* store programm counter for later return */
...@@ -22,7 +22,7 @@ __fiber_continue: ...@@ -22,7 +22,7 @@ __fiber_continue:
/* Perform change to new stack */ /* Perform change to new stack */
/* Keep old stack as result from this function. */ /* Keep old stack as result from this function. */
mov r4, sp mov r1, sp
/* Switch to new stack pointer. */ /* Switch to new stack pointer. */
mov sp, r0 mov sp, r0
...@@ -34,5 +34,5 @@ __fiber_continue: ...@@ -34,5 +34,5 @@ __fiber_continue:
/* Just return back from the call. */ /* Just return back from the call. */
/* This is the end of a fiber, so we have no continuation. */ /* This is the end of a fiber, so we have no continuation. */
mov r0, r4 mov r0, r1
pop {pc} pop {pc}
...@@ -11,9 +11,6 @@ __fiber_continue: ...@@ -11,9 +11,6 @@ __fiber_continue:
# Return # Return
# rax = continuation that returned control back to the caller (null if fallthrough) # rax = continuation that returned control back to the caller (null if fallthrough)
# Variables
# r12 = temporary for the old stack pointer
############### Save State ############### ############### Save State ###############
# Make space for all register state we will store. # Make space for all register state we will store.
leaq -0x38(%rsp), %rsp leaq -0x38(%rsp), %rsp
...@@ -33,7 +30,7 @@ __fiber_continue: ...@@ -33,7 +30,7 @@ __fiber_continue:
# Perform change to new stack. # Perform change to new stack.
# Keep old stack as result from this function # Keep old stack as result from this function
movq %rsp, %r12 movq %rsp, %rax
# switch to new stack pointer # switch to new stack pointer
movq %rdi, %rsp movq %rdi, %rsp
...@@ -55,5 +52,5 @@ __fiber_continue: ...@@ -55,5 +52,5 @@ __fiber_continue:
############ Restore State ############ ############ Restore State ############
# Return the context we came from as a continuation. # Return the context we came from as a continuation.
movq %r12, %rax # Result is already in rax.
ret ret
import numpy as np import numpy as np
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.patches import Patch
labels = ['loop overhead', labels = ['loop overhead',
'function call', 'function call',
'stack switching', 'stack switching',
'setjmp + stack switching', 'setjmp and stack switching',
'fcontext switch, return', 'minimal fcontext overhead',
'fcontext create, switch, return', 'minimum callcc overhead',
'pseudo callcc', 'custom assembly'
'custom'
] ]
call_color = (0.3, 0.1, 0.4, 0.6) call_color = (0.3, 0.1, 0.4, 0.6)
...@@ -22,7 +22,6 @@ colors = [ ...@@ -22,7 +22,6 @@ colors = [
setjmp_color, setjmp_color,
fcontext_color, fcontext_color,
fcontext_color, fcontext_color,
fcontext_color,
custom_color custom_color
] ]
...@@ -31,29 +30,57 @@ dataX86 = np.array([ ...@@ -31,29 +30,57 @@ dataX86 = np.array([
2.79, 2.79,
5.60, 5.60,
14.93, 14.93,
9.51,
11.00, 11.00,
18.66, 18.66,
7.86, 7.86,
]) ])
dataARM32 = np.array([ # TODO: Run and fill in data...damn that laptop crash dataARM32 = np.array([
1.26, 1.26,
4.97, 4.97,
11.25, 11.25,
54.50, 54.50,
51.93,
57.45, 57.45,
101.29, 101.29,
23.74, 23.74,
]) ])
data = dataARM32
assert (len(labels) == len(data), "Must fill in all data!")
xAxis = np.array(range(0, len(labels)))
plt.bar(xAxis, data, color=colors) def plot_data(data, name):
plt.xticks(xAxis, labels, rotation=90) plt.clf()
plt.ylabel('runtime in ns')
plt.subplots_adjust(bottom=0.5, top=0.98) # Make sure pgf plots have correct fonts
pgf_with_rc_fonts = {
"font.family": "serif",
"font.serif": [""],
"font.sans-serif": [""],
}
plt.rcParams.update(pgf_with_rc_fonts)
xAxis = np.array(range(0, len(labels)))
plt.bar(xAxis, data, color=colors)
plt.xticks(xAxis, labels, rotation=90)
plt.ylabel('runtime in ns')
plt.subplots_adjust(bottom=0.5, top=0.98)
custom_lines = [Patch(facecolor=call_color, edgecolor='k'),
Patch(facecolor=setjmp_color, edgecolor='k'),
Patch(facecolor=fcontext_color, edgecolor='k'),
Patch(facecolor=custom_color, edgecolor='k')]
custom_labels = ['baseline',
'setjmp',
'fcontext',
'custom']
plt.legend(custom_lines, custom_labels)
fig = plt.gcf()
fig.set_size_inches(5, 5)
fig.set_dpi(300)
# bounds = Bbox.from_bounds(-0.1, -0.1, 4.75, 4.6)
fig.savefig(name + '.pgf')
fig.savefig(name + '.png')
plt.show() plot_data(dataX86, "plots/context_switch_x86_64")
plot_data(dataARM32, "plots/context_switch_arm32")
# Context Switch Measurements
The goal of these 'quick and dirty' measurements is to get a feeling for the
expected minimum runtime of different operations involved in cotext switching/
stackfull coroutines.
We compare a jump_buf + stack pointer manipulation method, boost.context (represented
the c wrapper around their assembly to avoid importing whole boost), a custom
fiber call written by us in assembly and finally some baseline for method call costs.
We plot the results for both an x86_64 and arm32 system to decide what implementation
we choose for pls, as this operation will be performed for every single task creation.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment